美文网首页Java
java什么时候发生类的初始化

java什么时候发生类的初始化

作者: 小白拌豆腐 | 来源:发表于2020-05-22 16:52 被阅读0次

    会发生类初始化的情况(5点)

    1.虚拟机启动时,初始化main方法所在的类。

    2.调用类的静态成员(final修饰除外),静态方法。

    3.new一个类的对象

    4.初始化一个类,其父类先被初始化,

    下面一个例子概括前4点

    public class Text {
    
        static {
            System.out.println("main类被加载!");
        }
        public static void main(String[] args) throws ClassNotFoundException {
            Son son =new Son(); 
        }
    }
    
    class Son extends Father{   //Son类继承Father类
        static {
            System.out.println("Son类被加载!");
        }   
    }
    
    class Father{
    
        static {
            System.out.println("Father类被加载!");
        }
    } 
    

    运行结果是:

    main类被加载!
    Father类被加载!
    Son类被加载!
    

    5.使用java.lang.reflect包的按方法对类反射调用

    上例子:

    public class Text03 {
    
        static {
            System.out.println("main类被加载!");
        }
        public static void main(String[] args) throws ClassNotFoundException {
            Class.forName("text.Son");  
        }
    }
    class Son extends Father{
    
        static {
            System.out.println("Son类被加载!");
        }   
    }
    class Father{
        static {
            System.out.println("Father类被加载!");
        }
    }
    

    运行结果,与实例化Son类一样:

    main类被加载!
    Father类被加载!
    Son类被加载!
    

    不会发生类初始化(3点)

    1.子类引用父类变量

    如下:在Father类中声明一个静态变量

    static int fat=100;
    

    接下来,我们直接用子类来引用父类中的静态变量,代码如下:

    public class Text03 {
    
        static {
            System.out.println("main类被加载!");
        }
        public static void main(String[] args) throws ClassNotFoundException {
            System.out.println(Son.fat);
        }
    
    }
    class Son extends Father{
        static {
            System.out.println("Son类被加载!");
        }   
    }
    class Father{
        static int fat=100;
        static {
            System.out.println("Father类被加载!");
        }
    }
    
    

    结果显示:

    main类被加载!
    Father类被加载!
    100
    

    在输出语句中可以看出,子类引用父类静态变量是,没有被初识化

    2.引用常量

    如果我们把变量换成常量,即用final修饰,不可被重写

    static final int fat=100;
    

    其他代码与上述不变

    public class Text03 {
        static {
            System.out.println("main类被加载!");
        }
        public static void main(String[] args) throws ClassNotFoundException {
            System.out.println(Son.fat);
        }
    }
    class Son extends Father{
        static {
            System.out.println("Son类被加载!");
        }       
    }
    class Father{
        static final int fat=100;
        static {
            System.out.println("Father类被加载!");
        }
    }
    

    结果显示:

    main类被加载!
    100
    

    没有出现父类被初识化
    因为:常量在链接阶段,就存入调用类的常量池中了

    3.通过数组定义 类引用,也不会触发此类的初识化

    public class Text03 {
        static {
            System.out.println("main类被加载!");
        }
        public static void main(String[] args) throws ClassNotFoundException {
            Son [] son=new Son[5];
        }
    }
    class Son extends Father{
        static {
            System.out.println("Son类被加载!");
        }       
    }
    class Father{
        static {
            System.out.println("Father类被加载!");
        }
    }
    

    输出结果:

    main类被加载!
    

    相关文章

      网友评论

        本文标题:java什么时候发生类的初始化

        本文链接:https://www.haomeiwen.com/subject/jfaqahtx.html