-1

What is the difference between public, protected, package-private and private in Java? The question's answer cannot answer my question. It's not a duplicate question. I totally know the diagram of access modifier. I've cited the java doc: The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package. However, it cannot answer my following question:

I have a Java project with the following file structure:

src
└── A
    ├── P1.java

└── P2.java

P1.java is inside package A, while P2.java is at the same level as A.

Here is the code for P1.java:

package A;

public class P1 {
    public int a1;
    protected int a2;
}

And here is the code for P2.java:

import A.P1;

public class P2 extends P1 {
    public static void main(String[] args) {
        P1 p = new P1();
        System.out.println(p.a1);
        System.out.println(p.a2); // error? 
    }
}

When I run this, I get the following error:

java: a2 has protected access in A.P1

However, I recall that a protected variable should be accessible in a subclass, even if they are not in the same package.

Why is this happening? Since P2 is a subclass of P1, it should be able to access a2.

4
  • The relevant bit of the language spec is JLS 6.6.2, which explains why this access is not permitted. Commented Jul 2 at 22:41
  • This answer in the duplicate may help: stackoverflow.com/a/20009675/3788176 Commented Jul 2 at 22:46
  • Also: "P2.java is at the same level as A" despite the appearance, Java packages aren't hierarchical. All classes belong to a package; P2 is just in the default package, which is the same "level" as all top-level classes. Commented Jul 2 at 22:52
  • I guess it's because you defined P2 in the default (unnamed) package, but I'm not 100% sure. In any case, you should always use only the default package (and that only for toy projects), or only named packages, not a combination. Commented Jul 3 at 10:52

1 Answer 1

0

This is happening because you are accessing the protected member using the object of the superclass, which is not possible. The accessibility of protected member is only possible with the object of the subclass itself.

Try:

import A.P1;

public class P2 extends P1 {
    public static void main(String[] args) {
        P2 p = new P2();
        System.out.println(p.a1);
        System.out.println(p.a2);
    }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.