При поиске по языковой спецификации Java для ответа на этот вопрос я узнал что
Прежде чем инициализировать класс, его прямой суперкласс должен быть инициализировано, , но интерфейсы, реализованные классом, не являются инициализировано. Аналогично, суперинтерфейсы интерфейса не являются инициализируется до инициализации интерфейса.
Для моего собственного любопытства я попробовал это и, как и ожидалось, интерфейс InterfaceType
не был инициализирован.
public class Example {
public static void main(String[] args) throws Exception {
InterfaceType foo = new InterfaceTypeImpl();
foo.method();
}
}
class InterfaceTypeImpl implements InterfaceType {
@Override
public void method() {
System.out.println("implemented method");
}
}
class ClassInitializer {
static {
System.out.println("static initializer");
}
}
interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();
public void method();
}
Эта программа печатает
implemented method
Однако, если интерфейс объявляет метод default
, тогда происходит инициализация. Рассмотрим интерфейс InterfaceType
, указанный как
interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();
public default void method() {
System.out.println("default method");
}
}
тогда одна и та же программа напечатала бы
static initializer
implemented method
Иными словами, поле static
интерфейса инициализируется (шаг 9 в подробной процедуре инициализации) и static
выполняется инициализатор инициализированного типа. Это означает, что интерфейс был инициализирован.
Я не мог найти ничего в JLS, чтобы указать, что это должно произойти. Не поймите меня неправильно, я понимаю, что это должно произойти в случае, если класс реализации не обеспечивает реализацию метода, но что, если это произойдет? Является ли это условие отсутствующим в спецификации языка Java, я что-то пропустил или неправильно интерпретирую его?