3

If a class is private then must the constructor be private as well?

CloudyMarble
  • 36,908
  • 70
  • 97
  • 130

5 Answers5

4

No, there is no such restriction. See JLS §8.8.3. Constructor Modifiers.

It's worth pointing out that only a nested class can be declared private. The JLS permits the constructors for such a class to use any valid access modifiers.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
3

If you mean nested class, the answer is no. Making the inner class private makes it only usable within the outer class.

Edit: It appears that outer classes have full access to the innards of the inner classes regardless of their access modifiers. This invalidates my above reasoning, but regardless, there is no such restriction. Curiously though, now it appears that if the inner class is private, its constructor is essentially private, regardless of its access modifier, since noone else can call it.

Karthik T
  • 31,456
  • 5
  • 68
  • 87
  • 1
    Are you quite sure about this? I've done a couple of experiments, and I can create an instance of the inner class from the outer class *even if the inner class's constructor is `private`*. – NPE Mar 13 '13 at 09:22
  • @NPE I was going based on logic, but it seems like you are right, it is tackled at [Why can outer Java classes access inner class private members?](http://stackoverflow.com/q/1801718) where the accepted answer is unfortunately backwards.. – Karthik T Mar 13 '13 at 09:28
  • 1
    A general rule in Java is that all `private` members are accessible throughout the outermost lexical scope in which they occur. – Marko Topolnik Mar 13 '13 at 09:29
  • @NPE is right, inner classes' private constructors are accessible from outer class instances. This is because inner classes (not: nested classes) count as part of the outer class instance. See examples my answer: http://stackoverflow.com/a/15381486/1208581 – sulai Mar 13 '13 at 09:36
1

No it hasn't. On the contrary, if you create an instance of the inner class using a private constructor (which is default for a private class) from the outer class Java will create an additional class to prevent access violation and keep JVM happy

If you compile this class

class Test {
    private class Test2 {
        Test2() {
        }
    }
    Test() {
        new Test2();
    }
}

javac will create Test.class, Test@Test2.class

and if you compile this class

class Test {
    private class Test2 {
    }
    Test() {
        new Test2();
    }
}

javac will create Test.class, Test@Test2.class, Test$1.class

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
0

No it is not fix, you can set it private/public/any you want.

But in some case I prefer to make constructor private, when you don't want to allow other classes to create object of this class. then in that case you can do something like this, by setting constructor private.

private class TestClass{
    private TestClass testClass=null;
    private TestClass(){
         //can not accessed from out side
         // so out side classes can not create object
         // of this class
    }

    public TestClass getInstance(){
      //do some code here to
      // or if you want to allow only one instance of this class to be created and used
      // then you can do this
      if(testClass==null)
           testClass = new TestClass();

      return testClass;
    }
}

Btw it depends on your requirement.

Patriks
  • 1,012
  • 1
  • 9
  • 29
0

It does not have to be private. But it can. Example:

public class Outer {

    // inner class with private constructor
    private class Inner {
        private Inner() {
            super();
        }
    }

    // this works even though the constructor is private.
    // We are in the scope of an instance of Outer
    Inner i = new Inner();

    // let's try from a static method
    // we are not in the scope of an instance of Outer
    public static void main(String[] args) {

        // this will NOT work, "need to have Inner instance"
        Inner inner1 = new Inner();

        // this WILL work
        Inner inner2 = new Outer().new Inner();
    }
}

// scope of another class
class Other {
    // this will NOT work, "Inner not known"
    Inner inner = new Outer().new Inner(); 
}

It doesn't make a difference if you use private or public constructor on private inner classes. The reason is that the inner class instance is part of the outer class instance. This picture says it all:

Inner class is part of the outer class. That's why all private members of the inner class can be accessed from the outer class.

Note that we are talking about an inner class. If the nested class was static, the official terminology is static nested class, which is different from an inner class. A public static nested class would be accessible without outer class instance just by calling new Outer.Inner(). See here for more information about inner- and nested classes. http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

sulai
  • 5,204
  • 2
  • 29
  • 44