【JAVA】在编译期可直接替换的final变量

一、满足以下三个条件,一个final变量就不再是一个变量,而是一个直接量。

  1. 使用final修饰符修饰。
  2. 在申明的时候就进行初始化
  3. 初始化的值在编译器就可以确定。

二、在什么情况下初始化的值在编译期是可以确定下来的?

  被赋的表达式只是基本的算术表达式或字符串链接运算,没有访问普通变量,调用方法。  

package fianlFieldCase;

public class Test {

    public static void main(String[] args) {
        
        final String str1 = "final" + "field";
        final String str2 = "java" + 8;
        
        //下面的str3的值因为调用了方法,所以值在编译期不能确定
        final String str3 = "java" + String.valueOf(8);
        final int a = 2 + 3;
        final double b = 1.5 / 3;
        System.out.println("java8" == str2);
        System.out.println("java8" == str3);
    }
}

  编译以后的class文件如下:

  从编译以后的结果可以看出,除了str3,其他变量的值在编译期间就可以确定下来的。由于str2是一个直接量,它直接被替换成"java8",str2便指向字符串常量池中的"java8",所以当"java8"和str2进行==比较的时候直接返回true。但是str3的值要在运行期才能确定,这样就不能指向常量池中的”java8“。

  常量池是专门用于管理在编译期被确定并被保存在已编译的class文件中的一些数据。它包括了关于类、方法、接口中的常量,还包括字符串常量。

  例如执行String a = "java",就会在字符串常量区缓存一个"java";当再执行String b = "java",b就直接指向刚刚缓存的"java"。所以a==b 返回true。

 

  

posted @ 2015-08-05 22:27  grace_sister  阅读(1677)  评论(0编辑  收藏  举报