6.4.4 可执行 宏替换 的final变量

6.4.4 可执行 宏替换的 final变量

什么样的final变量可以当成直接量

对一个final变量来说,不管它是类变量、实例变量,还是局部变量,只要该变量满足两个条件这个final变量就不再是一个变量,而是相当于一个直接量。

  • 在定义该final变量时指定了初始值。
  • 该初始值可以在编译时就被确定下来。

编译器会将final直接量变量 直接 替换成对应的值

当定义final变量时就为该变量指定了初始值,而且该初始值可以在编译时就确定下来,那么这个final变量本质上就是一个”宏变量”,编译器会把程序中所有用到该变量的地方直接替换成该变量的值

字符串直接量

Java会使用常量池来管理曾经用过的字符串直接量,例如执行String a="java";语句之后,常量池中就会缓存一个字符串"java";如果程序再次执行String b="java";系统将会让b直接指向常量池中的"java"字符串,因此a==b将会返回true

final变量当成宏变量处理的情况

  • 定义final变量时要直接赋值,赋值可以是一个简单的直接量,也可以是一个表达式
  • 如果被赋的表达式只是基本的算术表达式字符串连接运算,则Java编译器同样会将这种final变量当成”宏变量”处理。

注意:如果赋值表达式包含了普通变量,或者调用了方法则不会当成”宏变量”处理.

对于final实例变量而言,只有在定义该变量时指定初始值才会有”宏变量”的效果

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class FinalReplaceTest
{
public static void main(String[] args)
{
// 算术表达式,会被当成"宏变量"
final int a = 5 + 2;
// 算术表达式,会当成"宏变量"
final double b = 1.2 / 3;
// 字符串直接量的连接,并且是final修饰的 所以str会被当成"宏变量"
final String str1="HelloWorld";
final String str2 = "Hello" + "World";
// 是同一个对象,输出true
System.out.println(str1==str2);
// 字符串直接量和数值直接量的链接,而且是final修饰的所以变量book会被当成"宏变量"
final String book = "HelloWorld" + 99.0;
// 调用了方法,会生成新对象
final String book2 = "HelloWorld" + String.valueOf(99.0);
double num=99.0;
// 调用了变量num,不是直接量
final String book3="HelloWorld"+num;
// HelloWorld99.0
System.out.println(book3);
// 相等,是同一字符串对象,输出true
System.out.println(book == "HelloWorld99.0");
// 不相等,不是同一个字符串对象,输出
System.out.println(book2 == "HelloWorld99.0");
// 不相等,不是同一个字符串对象,输出
System.out.println(book3 == "HelloWorld99.0");
}
}

这个示例并不严谨,这本质上是String直接量
运行结果:

1
2
3
4
5
true
HelloWorld99.0
true
false
false