欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

<clinit> 方法和 <init> 方法有什么区别?

程序员文章站 2022-03-05 15:38:54
...

首先要了解< clinit > 方法是类初始化方法,而< init > 方法是对象初始化方法,同时JVM 会保证在子类的初始化方法执行之前,父类的初始化方法已经执行完毕。

测试demo:

/**
 * <clinit> 方法和 <init> 方法有什么区别?
 */
public class CinitAndInit {
    static class A {
        static {
            System.out.println("A的静态块");
        }

        public A() {
            System.out.println("A的构造方法");
        }
    }

    static class B extends A {
        static {
            System.out.println("B的静态块");
        }

        public B() {
            System.out.println("B的构造方法");
        }
    }

    public static void main(String[] args) {
        A ab = new B();
        ab = new B();
    }
}

运行结果:<clinit> 方法和 <init> 方法有什么区别?
第一个红框的输出结果对应第一段代码,因为是第一次构造B类的实例对象,需要先做类加载,所以会做类的初始化操作,而static块属于类,同时B类又是A类的子类,所以会首先完成A类的初始化,然后再初始化B类,因此先输出了A,B类的静态块中内容,这时调用的是< clinit > 方法,而后才开始做对象的初始化,这时候就会调用类的构造方法 < init > 方法,所以先后调用了A,B类的构造方法,输出了两个类构造方法中的内容。

第二段代码就只输出了A,B类构造方法中的内容,因为B类和A类都已经被加载到方法区了,所以无需再做类加载操作,因此不会再调用< clinit > 方法。

总结

< clinit > 方法是类的初始化方法,而< init > 方法是对象的初始化方法,
< clinit > 方法只会在类需要被加载时,才会被调用到,除非类被卸载了,不然一般只会被调用一次,而< init > 方法则是只要有初始化对象的操作(除了反序列化和使用 Object 的 clone 方法),就会被调用。

相关标签: JVM