首页 > 如何理解:在父类中如果有常量属性,在子类中使用常量属性时是不会进行父类的类加载。

如何理解:在父类中如果有常量属性,在子类中使用常量属性时是不会进行父类的类加载。

是不是因为父类编译时会生成常量,而子类在使用时已经有常量了,不需要再对父类进行加载。


一个类的静态代码块和静态常亮的使用,不依赖于类的加载的。也就是使用一个类的静态变量并不会触发该类的加载。

/**
 * Created by gongxufan on 3/31/16.
 */
class Parent{
    public static final String const_str = "Super";
    static{
        System.out.println("Super Class Init");
    }
    public Parent(){
        System.out.println("Super Class Init");
    }
}

class Child extends Parent{
    public static final String const_str_child = "Super";
    static {
        System.out.println("Child Class Init");
        System.out.println(const_str);
    }
}
public class SuperClassInit {
    public static void main(String[] args) {
        System.out.println(Child.const_str);
    }
}

加载子类会先加载父类
我写了代码下面:
Super

public class Super
{
    public static final int FIELD = 1;

    public static int FILED1 = 2;

    static {
        System.out.println("Super");
    }
}

Sub

public class Sub extends Super
{
    static {
        System.out.println("out main");
    }
    public static void main(String[] args)
    {
        System.out.println(FIELD);
        System.out.println(FILED1);
    }
}

输出是:

Super

out main
1
2

会加载父类,你说的问题是什么样的?


补充:

public class Demo {

    public static void main(String[] args) {
        System.out.println(Child.const_str);
        System.out.println(Child.const_str_child);
    }
}
class Parent{
    public static final String const_str = "P";
    static{
        System.out.println("P Init");
    }
}

class Child extends Parent{
    public static final String const_str_child = "C";
    static {
        System.out.println("C Init");
    }
}

运行结果:

P
C

注意:

public class Demo {

    public static void main(String[] args) {
        System.out.println(Child.const_str);
        System.out.println(Child.const_str_child);
    }
}
class Parent{
    public static String const_str = "P";
    static{
        System.out.println("P Init");
    }
}

class Child extends Parent{
    public static String const_str_child = "C";
    static {
        System.out.println("C Init");
    }
}

常量中final去掉,则结果:

P Init
P
C Init
C

jdk1.8
之所以会出现这种情况是因为final由于其不变性,在编译时进行优化,System.out.println(Child.const_str)编译后直接指向该字符串在常量池中的位置。


在加载子类时候,父类是一定会被加载的。
在JVM 的加载顺序中,必然是先加载父类,然后才是子类的初始化。

没记错的话顺序是 父类的静态变量 -- 父类的静态代码块 -- 子类的静态变量 -- 子类的静态代码块。 顺序可能有记错。

【热门文章】
【热门文章】