Подтвердить что ты не робот

Является ли членский интерфейс в объявлении класса неявно общедоступным?

код

У меня есть следующий класс с интерфейсом-членом:

package com.example.withinterface;

public class SomeClass {

    interface SomeInterface {

        void doSomething();
    }
}

И еще один класс пытается получить к нему доступ:

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);
    }
}

Ошибка

В основном я получаю следующую ошибку от javac: SomeInterface is not public in SomeClass; cannot be accessed from outside package.

И в Eclipse: SomeInterface is not public in SomeClass; cannot be accessed from outside package.

Оба компилируются как Java 7. Все компилируется отлично, если я создаю SomeInterface public.

Но Spec говорит

Спецификация языка Java для Java 7 говорит следующее:

Пользовательский интерфейс - это интерфейс, декларация которого напрямую заключен в другое объявление класса или интерфейса.

Пользовательский интерфейс в объявлении класса является неявным публичным (§6.6) если не указан модификатор доступа.

Спецификация Java Language для Java 5, похоже, не имеет второго предложения.

Вопрос

Поэтому не следует ли считать SomeInterface общедоступным и не должен компилироваться Main?

Обновление

Как было предложено Ajay George, это действительно было ошибка в спецификации языка Java 7 (спасибо JamesB). Тем временем спецификация была скорректирована, а неправильное предложение было удалено. Последняя версия в Archive.org с неправильным предложением.

4b9b3361

Ответ 1

Я предполагаю, что спецификация ошибочна. Вот код javap с вашим кодом.

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();
}

Я изменил интерфейс на публичный, а затем перекомпилировал его.

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();
}

Обратите внимание на разницу в классе Inner.