Consider the following clause from JLS 8: § 15.9.5.1. Anonymous Constructors
Note that it is possible for the signature of the anonymous constructor to refer to an inaccessible type (for example, if such a type occurred in the signature of the superclass constructor cs). This does not, in itself, cause any errors at either compile-time or run-time.
I tried to generate an example for this - and came up with the following:
.
└── com
└── example
├── inaccessible
│ └── InaccessibleType.java
├── subclass
│ └── SubClass.java
└── superclass
└── SuperClass.java
And the code being the following:
-> InaccessibleType.java
package com.example.inaccessible;
public class InaccessibleType {
public void display() {
System.out.println("InaccessibleType instance");
}
}
-> SuperClass.java
package com.example.superclass;
// Importing the superclass
import com.example.inaccessible.InaccessibleType;
public class SuperClass {
public SuperClass(InaccessibleType it) {
it.display();
}
}
-> SubClass.java
package com.example.subclass;
import com.example.superclass.SuperClass;
public class SubClass {
public static void main(String[] args) {
// Creating an anonymous class that extends SuperClass
SuperClass instance = new SuperClass(new InaccessibleType() {
// This anonymous class does not have access to InaccessibleType
}) {
// Anonymous constructor referring to InaccessibleType
// No errors here even though InaccessibleType is inaccessible
};
}
}
Now despite the above statement given in the JLS - I am still getting compilation error in the subclass
javac com/example/inaccessible/*.java com/example/subclass/*.java com/example/superclass/*.java ─╯
com/example/subclass/SubClass.java:8: error: cannot find symbol
SuperClass instance = new SuperClass(new InaccessibleType() {
^
symbol: class InaccessibleType
location: class SubClass
1 error
Now sure - if my understanding of the above clause correct? - and what can be the example that explains the above clause correctly?
"Inaccessible" in this case does not mean "cannot refer to it using its simple name". It means "inaccessible as per the rules of Access Control".
According to the rules of Access Control, InaccessibleType
is totally accessible in Subclass
because it is public
. You just need to say com.example.inaccessible.InaccessibleType
, or InaccessibleType
if you import it.
One example of the situation that the JLS is talking about is,
public class Superclass {
private static class Nested {}
public Superclass(Nested n) {}
}
Superclass.Nested
is inaccessible outside of Superclass
. In some other class, I can create an anonymous class inheriting Superclass
:
new Superclass(null) { };
This anonymous class will have a constructor that takes a parameter of type Superclass.Nested
. The JLS says that this is OK. This code compiles and runs as expected.
In contrast, you cannot create a non-anonymous subclass of Superclass
that has a constructor with the same signature:
class Subclass extends Superclass {
public Subclass(Superclass.Nested n) { // This will produce an error
super(n);
}
}