gpt4 book ai didi

java - 一次性局部变量是final的是什么意思?

转载 作者:行者123 更新时间:2023-12-02 08:49:00 25 4
gpt4 key购买 nike

在使用现有代码库时,我遇到了与此类似的情况。

public static int getDatePlusDaysInMillis(int days) {
final int DAY = 24 * 60 * 60 * 1000;

return System.currentTimeMillis() + DAY * days;
}

逻辑本身并不重要,因为我稍微修改了代码,所以我没有复制和粘贴业务代码。

我想引起人们注意的是final int DAY。有什么理由将 DAY 声明为 final 吗?它的作用域仅限于此方法,并且仅在其中使用一次。它不会伤害任何东西,但我认为它看起来很奇怪,想问一下这个变量被声明为 final 是否有任何意义。

最佳答案

是的,这样做是有道理的。当声明 final 时,变量 DAY 是 Java 语言规范 ( §4.12.4 ) 定义的常量变量:

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).

这意味着一些优化是在编译时完成的,当变量未声明为final时,这些优化不会完成。根据您是否使用final,我们可以看到不同的字节码:

public class Test {
public long withoutFinal(int days) {
int DAY = 24 * 60 * 60 * 1000;
return System.currentTimeMillis() + DAY * days;
}
public long withFinal(int days) {
final int DAY = 24 * 60 * 60 * 1000;
return System.currentTimeMillis() + DAY * days;
}
}

编译为:

  public long withoutFinal(int);
Code:
0: ldc #2 // int 86400000
2: istore_2
3: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J
6: iload_2
7: iload_1
8: imul
9: i2l
10: ladd
11: lreturn

public long withFinal(int);
Code:
0: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J
3: ldc #2 // int 86400000
5: iload_1
6: imul
7: i2l
8: ladd
9: lreturn

带有 final 的版本较短,因为它使用一个 ldc(加载常量)操作,而另一个版本使用 ldc,一个istore_2 将常量存储到局部变量,以及 iload_2 从该局部变量加载常量。

如果多次调用该方法,JIT 可能会在运行时优化掉这种差异,但使用 final 意味着 .class 文件稍微小一些,并且如果该方法没有被多次调用,那么性能会有一点好处。

关于java - 一次性局部变量是final的是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60571988/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com