При поиске ответа на этот вопрос в спецификации языка 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, я что-то пропустил или неправильно интерпретирую?