Leigh Flix Leigh Flix - 7 months ago 15
Java Question

Different results when not using and using a access modifier with a constructor

I'm learning java and finally reached that point of getting into inheritance. I learned in the book I'm reading from that it is not necessary to put the "public" access modifier on a method/variable.

int showDim() { ... }; // both are the same because by default
public int showDim() { ... }; // not adding an access modifier will make it public.


So for a little review on the subject of inheritance with constructors, I created this small program:

A.java

package Default;

class A extends B {

A() { System.out.println("A constructor initiated"); }

public static void main(String ... args) {
A obj = new A();
}
}


B.java

package Default;

class B {

B() { System.out.println("B constructor initiated"); }
}


When I run the class A main method, this is the result:

A constructor initiated


Only the A constructor runs. However, when I precede public in front of both the A and B constructor, this is the result.

B constructor initiated
A constructor initiated


Why does this happen? I thought not adding an access modifier would by default make it public. Any reason for this? only reason I could theorize about is because the main method is running from inside the A class.

Answer

// not adding an access modifier will make it public.

Not true. Not adding an access modifier will give it the package default access modifier meaning it is only accessible from within the same class.

has 4 access modifiers (from most restrictive to less restrictive) :

  • private : access from same class
  • default : access from package (you don't need to specify it, default is a reserved keyword with another use
  • protected : access from package and from child classes
  • public : access from everywhere

When I run the class A main method, this is the result:

A constructor initiated Only the A constructor runs. However, when I precede public in front of both the A and B constructor, this is the result.

B constructor initiated

A constructor initiated

What actually happens is the following

A() {
    super(); <--- THIS IS ADDED AT COMPILATION CALLING B's CONSTRUCTOR
    System.out.println("B constructor initiated");
}

If you're in a different package, the code will not compile and you'll get the following compilation error

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    The constructor B() is not visible

    at A.<init>(A.java:7)
    at A.main(A.java:11)

The solution of course is to change the constructor's access modifier to public