【JAVA】在编译期可直接替换的final变量
一、满足以下三个条件,一个final变量就不再是一个变量,而是一个直接量。
- 使用final修饰符修饰。
- 在申明的时候就进行初始化
- 初始化的值在编译器就可以确定。
二、在什么情况下初始化的值在编译期是可以确定下来的?
被赋的表达式只是基本的算术表达式或字符串链接运算,没有访问普通变量,调用方法。
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。
做一名快乐的程序媛!欢迎大家多提提宝贵建议!