类加载之:可确定常量与不可确定常量

可确定常量

通常意义上的常量,都是可确定常量,对于可确定常量,在类加载时满足:常量在编译阶段会存入待调用这个常量的方法所在的类的常量池中,本质上。调用类并没有直接引用到定义常量的类,因此并不会触发定义常量的类的初始化

public class MyTest2 {
    public static void main(String[] args) {
        System.out.println(MyParent2.str);
    }
}
class MyParent2 {
    public static final String str = "hello world";
    static {
        System.out.println("MyParent2 static block.");
    }
}

以上代码的运行结果是:
可确定常量的运行结果
由上图的运行结果可以看出,MyParent2这个类并没有初始化,使用反编译工具在MyTest2这个类的常量池中可以看到字符串:hello world,进一步证明了:常量在编译阶段会存入待调用这个常量的方法所在的类的常量池中
因为hello world已经存入到MyTest2的常量池中了,所以在编译后,MyParent2.class就没有任何作用了,甚至我们可以把MyParent2.class文件删掉,再次运行,仍然可以正常运行。

不可确定常量

对于常量,普遍的认知是不可变的,但是在常量是一个随机字符串的情况下,每次运行,其值在运行前是不可确定的,但是在运行后就是确定的。这种常量,可以称之为:不可确定常量。如:public static final String str = UUID.randomUUID().toString();对于不可确定常量,上面的结论并不适用。

public class MyTest3 {
    public static void main(String[] args) {
        System.out.println(MyParent3.str);
    }
}

class MyParent3 {
    public static final String str = UUID.randomUUID().toString();
    static {
        System.out.println("MyParent3 static block.");
    }
}

其运行结果如下:
不可确定常量运行结果
由上图的运行结果可以看出来:不可确定常量,会导致定义该常量的类在运行时初始化。

结论:

  • 可确定常量:在编译阶段会存入待调用这个常量的方法所在的类的常量池中,本质上。调用类并没有直接引用到定义常量的类,因此并不会触发定义常量的类的初始化
  • 不可确定常量:当一个常量的值并非编译阶段可以确定的,那么其值就不会被放到调用类的常量池中。这时在程序运行时,会导致主动使用这个常量所在的类,显然会导致这个类被初始化。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值