2014-11-14 3 views
0

Интерфейс со стандартным методом инициализируется, даже если этот метод переопределен и даже если он вообще не вызывается.Интерфейс с методом по умолчанию Инициализация

Пример:

public interface I { 
    int a = foo(); 
    default void test1(){ 
    } 
    static int foo(){ 
     System.out.println("I initialized"); 
     return 15; 
    } 
} 


    public class C implements I{ 
    public void test2(){ 
      System.out.print("C initialized"); 
     } 
} 


    public class Test { 
     public static void main(String[] args) {  
     C c = new C(); 
     c.test2(); 
     } 
} 

печатает:

I initialized 
C initialized 

Что именно здесь проблема?

+0

В чем проблема? –

+0

В соответствии с JLS 8 в разделе 12.4.1 этот случай не инициирует инициализацию интерфейса –

ответ

0

Вы определили поле a; компилятор не знает, что вы никогда не получаете доступ к нему в реализации. Он должен запустить метод для определения значения.

int a = foo(); // <-- must run foo. 
static int foo(){ 
    System.out.println("I initialized"); // <-- prints I initialized 
    return 15; 
} 

и

a = 15 

и test1 не имеет ничего общего с test2, но даже если бы это было foo() все равно необходимо будет оцениваться установить a.

+0

Но согласно разделу JLS 12.4.1, вызов test2 должен инициализировать класс C и его суперклассы, но не его суперинтерфейсы. –

+0

[JLS-12.4.1] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.1) и прокрутите вниз * Пример 12.4.1- 3. Инициализация интерфейса не инициализирует Superinterfaces * и обратите внимание, что 'i = 1' печатает сначала (как в вашем вопросе), и здесь у вас нет интерфейса K. –

+0

Это связано с тем, что ссылка на статическое поле вызывает инициализацию только класса или интерфейса, которые фактически объявляют его. –

Смежные вопросы