编译时常量和运行时常量

在java中,static final修饰的是常量。根据编译器的不同行为,常量又可分为编译时常量和运行时常量。

举例说明吧

  • public static final int a = 10就是一个编译时常量,在编译后的符号中找不到a,所有对a的引用都被替换成了20;它是不依赖于类的,在编译时就可以确定值。
  • public static final int b = “hello”.length()就是一个运行时常量;它是依赖于类的,它的赋值会引起类的初始化。
  • 归根结底还是javac的编译机制导致了这样的结果。当涉及到方法的调用时,必须在运行的时候才能确定结果。

示例代码:

public class TestConstant {
    public static void main(String[] args) {
        System.out.println(Test.a);
        System.out.println(Test.s);
//      System.out.println(Test.b);
//      System.out.println(Test.a2);
//      System.out.println(Test.a3);
//      System.out.println(Test.e);
    }
}

class Test{
    static{
        System.out.println("Test正在被初始化");
    }
    public static final int a = 10;
    public static final int b = "test".length();
    public static final String s = "world";
    public static Integer a2 = 20;
    public static final A a3 = new A();
    public static final E e = E.A;
}
class A{

}
enum E{
    A,B,C,D,E,F,G
}
  • 挨个运行main函数中的打印语句,我们会发现编译时常量不会引起类的初始化,而运行时常量会引起类的初始化。

  • 通过运行我们还可以得出如下结论,编译时常量必须定义为基本类型或者String,而不可能是引用类型或者包装类、枚举。

一道面试题:编译时常量存在什么样的风险?

编译时常量,在使用时会被直接写成值,而不会再从原来的类中读取。这样就会导致问题的产生:如果A类定义了常量,B类使用了常量,并且都进行了编译。当A类的源码被改动了,常量的值发生了变化。我们对A类进行了重新编译,但是没有对B类进行重新编译;那么B类中用到的是原来A类中的常量值,即旧值。这就导致了风险的发生。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值