Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a member interface in a class declaration implicitly public?

Tags:

java

jls

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.

like image 759
Arend v. Reinersdorff Avatar asked Jul 24 '12 20:07

Arend v. Reinersdorff


People also ask

Are all members of an interface public?

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.

Can interface be declared as public?

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 .

Can a class declaration be a member of an interface?

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.

Can we declare interface members as private?

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”.


1 Answers

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.

like image 167
Ajay George Avatar answered Nov 15 '22 12:11

Ajay George