加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-15 02:16:22 所属栏目:Java 来源:网络整理
导读:我用Google搜索广泛但无济于事.我似乎无法围绕这个概念.为什么本地类接受静态最终字段?如下面的例子: public void sayGoodbyeInEnglish() { class EnglishGoodbye { public static final String farewell = "Bye bye"; public void sayGoodbye() { System.
我用Google搜索广泛但无济于事.我似乎无法围绕这个概念.为什么本地类接受静态最终字段?如下面的例子:

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允许变量告别?为什么?我糊涂了.为什么允许但没有静态变量?我理解为什么它不能访问封闭范围的成员,除非它们是编译器时间常量,因为当函数结束时这些变量不再存在但类可能不存在.对?我只是对此感到困惑.

谢谢!

解决方法

一般来说,这不是.

但告别是一种特殊的静态最终:一个值为常量,由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).

如果更改该行以删除最终修饰符或使表达式非常量(例如,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

多一点:

允许这样做的原因是编译器特别处理常量变量.特别是,它允许内联它们 – 结果字节码根本没有告别字段!如果您反编译该类(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:”行.程序没有加载字段告别的值,它的加载常量#3(它在注释中注释的是字符串“Bye bye”)(你可以看到字节码on wikipedia的列表).

因为告别是一个常量变量(而不是“真正的”静态成员),因此可以在代码中内联,在定义它的位置并不重要 – 变量的生命周期基本上是整个JVM的生命周期,而不是任何一个类或实例,因此它可以在任何地方声明.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读