public class Test
{
public static void main(String[] args)
{
System.out.println(Super.index);
System.out.println(Sub.index);
}
}class Super
{
public static int index; static 
{
index = 1;
}
}class Sub extends Super
{
static 
{
index = 2;
}
}
大家觉得分别会打印出什么呢?(先别运行看结果)

解决方案 »

  1.   

    super类使用了静态类,使得index的变量不会受到干扰,即使,sub继承了。super,但index属于静态块的成员,不会被重赋值。
      

  2.   

    你们没有说出真正的问题所在System.out.println(Super.index);
    System.out.println(Sub.index);
    第二个语句并不会使得Sub的static代码段执行,所以会打印 1,1
    但是如果你改为System.out.println(Super.index);
    new Sub();
    System.out.println(Sub.index);
    这样就会使得Sub中的static代码段执行就会打印1,2
      

  3.   

    静态块在子类中存在类似覆盖的时候,只是被隐藏了,不会覆盖原来的方法,所以子类中的那个static 块是没用的!故而:1,1
      

  4.   


    sub 类加载时不就要运行sub的静态代码块吗,为什么你说没执行?
      

  5.   

    都没说太透彻。其实,Sub类是没有index变量的,所以在编译期间,编译器就把Sub.index编译成了Super.index。这是名称查找机制,因为编译器在派生类中找不到相应的名称,就去它的超类中查找。所以,当执行到Sub.index时,实际上执行的是Super.index,这导致Sub类根本就没有被加载,从而它的static块也没有被执行。你可以试试在Sub中也定义一个public static int index; 结果就完全不同了,因为名称查找机制在派生类中找到了index,从而不会把Sub.index编译成Super.index,这样,运行时Sub得到了加载,它的static块也得到了执行。
      

  6.   

    所以,楼主的代码是含有误导性的,实际应用中应该避免。
    明智的做法是:如果一个类中没有定义某个静态成员,就不要用这个类名去引用该静态成员,即使可以通过名称查找机制引用到它,也不要这么做。
    如果把楼主的代码改成:public class Test
    {
        public static void main(String[] args)
        {
            System.out.println(Super.index);
            System.out.println(Super.index);
        }
    }class Super
    {
        public static int index;    static 
        {
            index = 1;
        }
    }class Sub extends Super
    {
        static 
        {
            Super.index = 2;
        }
    }编译的结果是完全一样的,但消除了误导性,可读性增强了。另外,通过实例变量引用类的静态成员,也不是很明智的做法。
      

  7.   


    在Class代码中,你可以看到编译器并没有把Sub.index变成Super.index,你可以用javap -classpath . Test -c看到
    Sub.index时,只是JVM觉得不需要初始化Sub,然后没有执行Sub的static代码而已
      

  8.   

    当然,我也觉得写Sub.index是一种不应该的写法,因为实际上是Super的静态变量
      

  9.   


    public class Test
    {
        public static void main(String[] args)
        {
            System.out.println(Super.index);
            Sub sub = new Sub();
            System.out.println(Sub.index);
        }
    }如果代码是这样,输出才是
    1
    2