Code
I have the following class with a member interface:
package com.example.withinterface;
public class SomeClass {
interface SomeInterface {
void doSomething();
}
}
And another class trying to access it:
package com.example.withinterface.main;
import com.example.withinterface.SomeClass;
public class Main {
public static void main(String[] argss) {
System.out.println(SomeClass.SomeInterface.class);
}
}
Error
In Main I get the following error from javac: SomeInterface is not public in SomeClass; cannot be accessed from outside package
.
And in Eclipse: SomeInterface is not public in SomeClass; cannot be accessed from outside package
.
Both compiling as Java 7. Everything compiles fine if I make SomeInterface public
.
But Spec says
The Java Language Specification for Java 7 says this:
A member interface is an interface whose declaration is directly enclosed in another class or interface declaration.
A member interface in a class declaration is implicitly public (§6.6) unless an access modifier is specified.
The Java Language Specification for Java 5 doesn't seem to have the second sentence.
Question
So shouldn't SomeInterface be considered public and shouldn't Main compile?
Update
As suggested by Ajay George this was indeed an error in the Java Language Specification 7 (thanks JamesB). In the meantime the spec was corrected and the incorrect sentence removed. Last version in Archive.org with the incorrect sentence.
Interface members are public by default, and you can explicitly specify accessibility modifiers, such as public , protected , internal , private , protected internal , or private protected . A private member must have a default implementation.
The Interface BodyAll abstract, default, and static methods in an interface are implicitly public , so you can omit the public modifier. In addition, an interface can contain constant declarations. All constant values defined in an interface are implicitly public , static , and final .
Yes, you can define a class inside an interface. In general, if the methods of the interface use this class and if we are not using it anywhere else we will declare a class within an interface.
Therefore, the members of an interface cannot be private. If you try to declare the members of an interface private, a compile-time error is generated saying “modifier private not allowed here”.
I guess the spec is wrong . Here is the javap output with your code.
E:\workspace>javap com\example\withinterface\SomeClass
Warning: Binary file com\example\withinterface\SomeClass contains com.example.wi
thinterface.SomeClass
Compiled from "SomeClass.java"
public class com.example.withinterface.SomeClass {
public com.example.withinterface.SomeClass();
}
E:\workspace>javap com\example\withinterface\SomeClass$SomeInterface
Warning: Binary file com\example\withinterface\SomeClass$SomeInterface contains
com.example.withinterface.SomeClass$SomeInterface
Compiled from "SomeClass.java"
interface com.example.withinterface.SomeClass$SomeInterface {
public abstract void doSomething();
}
I changed the interface to public and then recompiled it.
E:\workspace>javap com\example\withinterface\SomeClass
Warning: Binary file com\example\withinterface\SomeClass contains com.example.wi
thinterface.SomeClass
Compiled from "SomeClass.java"
public class com.example.withinterface.SomeClass {
public com.example.withinterface.SomeClass();
}
E:\workspace>javap com\example\withinterface\SomeClass$SomeInterface
Warning: Binary file com\example\withinterface\SomeClass$SomeInterface contains
com.example.withinterface.SomeClass$SomeInterface
Compiled from "SomeClass.java"
public interface com.example.withinterface.SomeClass$SomeInterface {
public abstract void doSomething();
}
Note the difference in the Inner class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With