Java类加载与初始化测试

一、定义一个父类:

public class SuperClass {
    static {
        System.out.println("SuperClass init");
    }
    public static int value = 123;
}

定义一个子类继承自父类:

public class SubClass extends SuperClass{
    static {
        System.out.println("SubClass init");
    }
}

测试类如下;

public class InitializationTest {
    public static void main(String[] args) {
        System.out.println(SubClass.value);
    }
}

运行结果;

SuperClass init
123

可见对于静态变量,只有直接定义这个变量的类才会被初始化。因此把main()方法里的SubClass.value换成SuperClass.value,运行结果是一样的。

二、把上面测试类的main()方法改成这样:

    public static void main(String[] args) {
//      System.out.println(SubClass.value);
        SuperClass sup = new SuperClass();
        SuperClass sub = new SubClass();
    }

运行结果:

SuperClass init
SubClass init

如果是改成这样:

    public static void main(String[] args) {
//      System.out.println(SubClass.value);
        SuperClass[] sups = new SuperClass[5];
        SuperClass[] subs = new SubClass[5];
    }

运行则不会产生任何输出,这表示通过数组定义来引用某类,不会触发此类的初始化。
实际上在这种情况下,虚拟机会自动生成一个直接继承于java.lang.Object的类,这个类代表了一个一维数组,数组应有的属性和方法都实现在这个类里。而上面的代码运行的时候,这个类会得到初始化。

三、在父类中添加一个静态常量做测试:

public class SuperClass {
    static {
        System.out.println("SuperClass init");
    }
    public static int value = 123;
    public static final int F_VALUE= 1234;//add
}

测试类;

public class InitializationTest {
    public static void main(String[] args) {
        System.out.println(SuperClass.F_VALUE);
    }
}

运行结果:

1234

并没有输入“SuperClass init”,可见SuperClass没有初始化。
常量在编译阶段会存入调用类(InitializationTest 类)的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。
调用类(InitializationTest 类)对常量SuperClass.F_VALUE的引用实际都被转化为InitializationTest 类对自身常量池的引用了。

四、父类里加上如下构造方法;

    SuperClass(){
        System.out.println("SuperClass constructor");
    };

测试类的main()方法如下:

    public static void main(String[] args) {
        System.out.println(SuperClass.value);
    }

运行结果:

SuperClass init
123

可见SuperClass的构造方法并没有得到调用。
而如果把main()方法改成这样;

    public static void main(String[] args) {
//      System.out.println(SuperClass.value);
        System.out.println(new SuperClass().value);
    }

运行结果:

SuperClass init
SuperClass constructor
123

构造方法就被调用了。说明构造方法只在创建对象的时候才会被调用,类的初始化不会触发调用。而且构造方法是在类初始化之后才调用的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值