当前位置: 首页 > 面试题库 >

方法本地类中的Java最终静态声明

松元明
2023-03-14
问题内容

在方法内部声明局部内部类时,为什么包含最终的静态String或int是合法的,而包含其他对象却不合法?

例如:

class Outer {
void aMethod() {
    class Inner {
        final static String name = "compiles";
        final static int ctr = 10; // compiles
        final static Integer intThree = Integer.valueOf(3); // does not compile!
        final static obj objConst = new Object(); // does not compile!
    }

    Inner inner = new Inner();
}
}

编译时,得到以下信息:

InnerExample.java:6: inner classes cannot have static declarations
        final static Integer outer = Integer.valueOf(3);
                             ^
InnerExample.java:7: inner classes cannot have static declarations
        final static Object objConst = new Object();
                            ^

为什么要区分?是因为String是不可变的吗?如果是这样,Integer.valueOf()也无效吗?


问题答案:

这是因为前两个静态成员分配给原始类型或String类型的编译时常量。

根据Java语言规范的第8.1.3节:

8.1.3。内部类和封闭实例

内部类不得声明静态成员,除非它们是常量变量(第4.12.4节),否则会发生编译时错误。

从4.12.4开始:

基本类型或String类型的变量是最终变量,并使用编译时常量表达式(第15.28节)进行了初始化,该变量称为常量变量。

编辑:

起初我发现这很令人惊讶。仔细考虑一下,此限制的一个优点是,无需担心何时初始化内部类的静态成员。您可以在包含类中移动内部类,而不必担心其静态成员的值将被更改。



 类似资料:
  • 问题内容: 将变量声明为的区别是什么 要么 如果我只希望变量是局部的,并且是常量(以后不能更改)? 谢谢 问题答案: 仅仅具有预期的效果。 声明static使其成为一个类变量,使其可以使用类名进行访问

  • 问题内容: 我理解这段代码: ..静态方法“隐藏”了声明的静态方法,而不是在多态性意义上覆盖它。 …将输出: 在Foo 中 重新定义为in 将禁用隐藏它的功能,并且重新运行将输出: 在Foo 中 ( 编辑 :将方法标记为时,编译失败,并且仅在我删除后再次运行) 如果将静态方法声明为,是否会阻止子类有意或无意地重新定义该方法,这是否被视为不好的做法? (这很好地说明了使用行为是..) 问题答案: 我

  • 问题内容: 给定下面的Java代码,您可以在Ruby类中最接近地表示这两个变量吗?而且,在Ruby中是否可以像Java中那样区分和变量? 问题答案: Ruby中确实没有等效的构造。 但是,您似乎犯了一个经典的移植错误:您有一种使用语言A 的 解决方案 ,然后尝试将其翻译为语言B,这时您真正应该做的就是找出 问题 ,然后找出解决方法使用语言B。 我不能完全确定您要从那个小的代码段中解决什么问题,但是

  • 问题内容: 我想模拟下一行: 这里的问题是newBigQueryClient方法返回的Bulder类是最终的。这意味着我既不能使用嘲讽也不可以使用powermockito来模拟它(它返回这样的异常:不能对最终类进行子类化),但是我需要返回适合于模拟它的构建方法的东西。有什么想法怎么做? 问题答案: 改善代码并使其更具可测试性的建议: 首先,您不会像您给我们的示例那样模拟 声明 。您可以模拟 对象

  • 问题内容: 假设以下内容: parsedUntil是否被视为静态变量?我注意到我无法在此静态函数中将其声明为静态。 后续问题:我读到一个静态变量只会被初始化一次。这是否意味着我第一次调用函数A()时,该值将设置为零,但是每隔一次我调用A()时,该行将被省略吗? 问题答案: 不,它不是静态变量。这是一个局部变量。方法中声明的任何变量都是局部变量。如果需要静态变量,则必须在方法外声明它: 没有办法声明

  • 问题内容: 我找到了一个代码,它声明了如下代码 它们之间有什么区别或相同?还是与或不同? 问题答案: 完全没有区别。根据 Java语言规范的8.3.1-类-字段修饰符, 如果两个或多个(不同的)字段修饰符出现在字段声明中,则按惯例(尽管不是必需的),它们的出现顺序与上面FieldModifier生产中所示的顺序一致。 对于字段,所述生产按以下顺序列出修饰符: 对于方法: