Question

Who is right? Eclipse or javac?

--------------- c/v/A.java ---------------

package c.v;
public class A<T> {
}

--------------- c/v/B.java ---------------

package c.v;
public class B extends A<B.Secret> {
  private class Secret {};
}

Eclipse compiles B.java just fine.

Javac has a problem.

$ javac c/v/B.java
c/v/B.java:3: c.v.B.Secret has private access in c.v.B
public class B extends A<B.Secret> {
                           ^
    1 error
Was it helpful?

Solution

The relevant parts of the Java Language Specification must be:

§8.1.4: [...] The ClassType must name an accessible (§6.6) class type, or a compile-time error occurs.

§6.6.1: [...] A member (class, interface, field, or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible and the member or constructor is declared to permit access:

  • If the member or constructor is declared public, then access is permitted. All members of interfaces are implicitly public. [...]
    • Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

So since the ClassType is not within the body of the class, B.Secret is not accessible at this location, so A<B.Secret> is not accesible, so a compile-time error should occur.

OTHER TIPS

Eclipse is wrong. If you advertise something as

extends A<X>

you need both to know about A, and X.

I would tend to think javac is right. In order to create a new class

A<B.Secret>

the generic needs to have access to the class it uses. The fact that B then extends that class is minor.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top