gpt4 book ai didi

java - 为什么本地类接受静态最终变量?

转载 作者:行者123 更新时间:2023-11-30 07:05:06 25 4
gpt4 key购买 nike

我已经用谷歌搜索了很多,但都无济于事。我似乎无法理解这个概念。为什么本地类接受静态最终字段?比如下面的例子:

public void sayGoodbyeInEnglish() {

class EnglishGoodbye {
public static final String farewell = "Bye bye";
public void sayGoodbye() {
System.out.println(farewell);
}
}
System.out.println(EnglishGoodbye.farewell);
EnglishGoodbye myEnglishGoodbye = new EnglishGoodbye();
myEnglishGoodbye.sayGoodbye();
}

在 EnglishGoodbye 类中允许使用变量告别?为什么?我很困惑。为什么允许但没有静态变量?我理解为什么它不能访问封闭范围的成员,除非它们是编译器时间常数,因为当函数结束时这些变量不复存在但类可能不存在。正确的?我只是对此感到困惑。

谢谢!

最佳答案

一般情况下不是。

但是 farewell 是一种特殊的 static final:它的值为常量,如 JLS 15.28 所定义。这意味着它没有在该位置初始化,根据 JLS 8.1.3,这实际上是非静态类(包括本地类)中不允许的。

JLS 在 8.1.3(注意“除非”部分)中明确(并以粗体显示):

It is a compile-time error if an inner class declares a member that is explicitly or implicitly static, unless the member is a constant variable (§4.12.4).

如果您更改该行以删除 final 修饰符或使表达式成为非常量(例如,new String("Bye bye")),则你会得到你期望的编译错误:

Test.java:5: error: Illegal static declaration in inner class EnglishGoodbye
public static final String farewell = new String("Bye bye");
^
modifier 'static' is only allowed in constant variable declarations
1 error

多一点:

这是允许的原因是常量变量被编译器特殊对待。特别是,允许​​内联它们——生成的字节码根本没有 farewell 字段!如果反编译该类 (javap -c YourClassName),您将看到如下内容:

public void sayGoodbyeInEnglish();
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Bye bye
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
...

上面对应这一行:

System.out.println(EnglishGoodbye.farewell);

这有点令人生畏,但请注意“3:”行。该程序没有加载字段 farewell 的值,它正在加载常量 #3(它在注释中注明是字符串“再见”)(您可以看到字节码列表 on wikipedia ).

因为 farewell 是一个常量变量(而不是“真正的”静态成员),因此可以在代码中内联,所以无论在哪里定义它都无关紧要——变量的生命周期本质上是整个 JVM,而不是任何一个类或实例,因此它可以在任何地方声明。

关于java - 为什么本地类接受静态最终变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27095847/

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