public class Test02 { public static void main(String[] args) {
System.out.println(J.i);
System.out.println(K.j); }
static int out(String s, int i) {
System.out.println(s + "=" + i);
return i;
}
}interface I {
int i = 1;
int ii = Test02.out("ii", 2);
}
interface J extends I {
int j = Test02.out("j", 3);
int jj = Test02.out("jj", 4);
}
interface K extends J {
int k = Test02.out("k", 5);
}
为什么调用K.j 能同时初始化j和jj  而调用 J.i 只初始化i 就不初始化ii  
很费解  希望大家能讨论下!
我看了 K.j   输出的是 j=3
                      jj=4
                      3
猜想是 调用父类接口属性就初始化父类中的所有属性而看了 J.i  只输出了1   那就不能用上面理解的解释了   大家都发表意见啊 

解决方案 »

  1.   

    一下子没看懂
    但我想了想看了下资料应该是这样方法必须是调用的时候JVM才会加载,  接口中定义的字段会自动具有static和final属性因此当(K.j); int j = Test02.out("j", 3);会调用out方法,一但加载了内存中也就存在了因此jj属性也得到了初始。类似的如果
    把int j = Test02.out("j", 3);改为int j =3;
    程序只输出1,3因为out方法没有初始化把(K.j);换成(K.jj);也是一样
    一般不使用这种常量接口,这个破坏了接口的本意
      

  2.   

    我怀疑是这样的:
    因为interface中的数据成员都是final的和static的.所以一般是在编译的时候就初始化好了的.
    而那些在运行时才可以初始化的成员,只会在需要的时候才进行初始化工作.一旦触发了初始化,就会把所有的可以初始化的成员进行初始化.J.i 的i这个成员是在编译时就初始化好的了,所以可以直接用.K.j 的j需要在运行时初始化,j是从父类J中继承过来的,这样就触发了对interface J的运行时初始化工作,会所有的成员都进行初始化.不知道对不对?
      

  3.   

    是这个意思
    public class Test02 { public static void main(String[] args) {
    //交换测试下
    //System.out.println(I.i);
    System.out.println(I.ii);
    } static int out(String s, int i) {
    System.out.println(s + "=" + i);
    return i;
    }
    }class I {
    static final int i = 1; static final int ii = Test02.out("ii", 2);
    }
      

  4.   

    按理说是接口中的变量默认为final static,是会同时初始化的。
    思考中!
      

  5.   

    我猜想:JVM的类加载机制是只用这个类用到的时候再去加载该类对象到JVM中
    K.j是调用了J类中的常量j,J类初始化j常量,让后调用Test02中的out方法而J.i会调用I类的常量i,因为没有用到I类中的ii常量,所以JVM就不会再把Test02类加载进JVM。这样也会提供JVM的效率
      

  6.   

    K.j  输出 j=3  jj=4  3 J.i  输出 1 这里解释不通啊
      

  7.   

    这是Interface的特性了
    调用K.j也同时意味着j变量所处接口(J)的初始化
    而接口的初始化则包含其所有成员变量初始化的计算和唯一一次的赋值(final)
    另:父接口的初始化不必先于子接口的初始化,此点不同于类(Class)
      

  8.   


    interface I {
        int i = 1;//因为这个域是编译时常量,不会引起接口I的初始化。
        int ii = Test02.out("ii", 2);
    }
      

  9.   

    测试,你换一下,把这个
    int i = 1;
    换成:
    int i = Test.out("i", 1);
      

  10.   

    这个i就不是编译时常量,引起接口I的初始化,导致ii也输出,结果就会变为:
    i=1
    ii=2
    1
      

  11.   

    Initialization of an interface consists of executing the initializers for fields declared in the interface.这里定义的接口初始化等价于执行接口中定义的域初始化体,类似于J.i等常量就不包含在此范围内了,编译时绑定已不需要在动态加载了吧
      

  12.   

    对,j.i不会引起接口I的初始化。
    另:
    调用K.j则不同,接口k里边的静态域都不是编译时常量,所以调用K.j会引起接口k的初始化,
    注意和类不同(一个类初始化的时候,会先初始化该类的超类),这里是接口,只会初始化该接口本身。
    类的初始化的时候,初始化真正定义域的类或者接口,比如这里的K.j,定义的变量j真正实在接口J中
    而不是K中,所以初始化J接口,而不是K接口。