Question

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.

Was it helpful?

Solution

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.

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