Visibility of a protected field of a class from a class in another package

Viewed 31
package test1.visibility;

public class Test {
    private int privateField = 1;
    int defaultField = 2;
    protected int protectedField = 3;
}
package test2.visibility;    

import test1.visibility.Test;
    
public class ExtendsTestOutsideThePackage extends Test {
    public static void main(String[] args) {
        Test tt = new Test();
        Test te = new ExtendsTestOutsideThePackage();
        ExtendsTestOutsideThePackage ee = new ExtendsTestOutsideThePackage();
    
        System.out.println(tt.privateField); //compilation error
        System.out.println(tt.defaultField); //compilation error
        System.out.println(tt.protectedField); //compilation error
    
        System.out.println(te.privateField); //compilation error
        System.out.println(te.defaultField); //compilation error
        System.out.println(te.protectedField); //compilation error
    
        System.out.println(ee.privateField); //compilation error
        System.out.println(ee.defaultField); //compilation error
        System.out.println(ee.protectedField); //works fine
    }
}
1. System.out.println(tt.protectedField); //compilation error
2. System.out.println(te.protectedField); //compilation error
3. System.out.println(ee.protectedField); //works fine

Can you explain why line 3 works fine, but not 1 and 2? Why cannot tt, and te objects access the "protectedField"? Why does Test reference fail to access the protectedField?

1 Answers

It's a consequence of your main method being inside of the subclass, similar to how you can access private variables of a class from within a static method of that same class:

public class Test {
    private int privateField = 1;

    public static void IncrementTest(Test test) {
         //we can access this because we're inside the class, even though 
         //we're not inside an INSTANCE of the class
         test.privateField++;
    }
}

In Java, regardless of if you're using a static method or an instance method, access modifiers work the same. The method just happens to be static.

  • We can see the protected variable, since we are within a subclass of Test.
  • We cannot see the private variable, because we are not the Test class.
  • We cannot see the "default" variable, because we are not in the same package.

If you move your main method to the Test class, you'll be able to access all 3 variables in the same way. If you move it to it's own class, you wont be able to see any of them. (assuming this new class is outside of the same package)

Related