2014-11-14 36 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

根据第12.4.1节中的JLS 8,这种情况不会触发接口初始化 –

回答

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。接口初始化不会初始化超级接口*并注意首先打印“i = 1”(如您的问题),并且您没有接口K。 –

+0

这是因为对静态字段的引用导致只初始化实际声明它的类或接口。 –