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

具有静态和最终限定符的奇怪Java行为

商琛
2023-03-14
问题内容

在我们的团队中,我们发现在使用staticfinal限定词时都有一些奇怪的行为。这是我们的测试课程:

public class Test {

    public static final Test me = new Test();
    public static final Integer I = 4;
    public static final String S = "abc";

    public Test() {
        System.out.println(I);
        System.out.println(S);
    }

    public static Test getInstance() { return me; }

    public static void main(String[] args) {
        Test.getInstance();
    }
}

运行该main方法时,将得到以下结果:

null
abc

我会理解它是否null两次都写值,因为静态类成员的代码是从上到下执行的。

谁能解释为什么这种现象发生?


问题答案:

这些是您运行程序时采取的步骤:

  1. main可以运行之前,Test必须按外观顺序通过运行静态初始化程序来初始化该类。
  2. 要初始化该me字段,请开始执行new Test()
  3. 打印的值I。由于字段类型为Integer,因此看起来像编译时常量4的值成为计算值(Integer.valueOf(4))。该字段的初始化程序尚未运行,正在打印初始值null
  4. 打印的值S。由于已使用编译时常数对其进行了初始化,因此将该值烘焙到引用站点print中abc
  5. new Test()完成,现在I执行初始化程序。

课程:如果您依赖急切初始化的静态单例,请将单例声明放置为最后一个静态字段声明,或者诉诸于在所有其他静态声明之后出现的静态初始化程序块。这将使该类看起来完全初始化为单例的构造代码。



 类似资料:
  • 问题内容: 我看到了我认为是错误的行为。@InjectMocks似乎并没有在每种测试方法之前创建一个新的测试主题。就像@Mock一样。在下面的示例中,如果Subject.section是最后一个,则@Test失败。如果不是最后两个都通过。我当前的解决方法是使用@BeforeClass,但这并不理想。 Subject.java: Section.java: SubjectTest.java 干杯。

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

  • 问题内容: 我在JTextPane / JTextField(或它们下方的字体渲染中的某个地方)中发现了一个奇怪的错误。我想知道是否有人遇到过这种情况,并且可能对此有解决方案。 我试图在JTextPane中显示一些“特殊”或稀有字符,并且一旦更改JTextField的字体(与JTextPane完全无关!),JTextPane就会“分手”,不再显示这些字符字符。 这应该可以更好地解释我的意思: 编辑

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

  • 我想知道这样的声明在Java是否有某种真正的意义。我在代码中发现了它几千次,但是我学习和玩字符串,我知道无论你声明一个对象多少次:如果你之前的某个类声明了这个字符串,它就会被汇集并重用(我说的是没有显式构造函数调用而创建的字符串) 事实上,这段代码在调用比较时打印,因此两个变量引用同一个对象。说变量无法重新定义,在这种情况下单词完全没有用。我是不是没抓住重点? 还有几件事: 1 - 为什么显式调用

  • 问题内容: 有一条规则说: 代表常量(最终变量)的名称必须全部使用大写字母,并使用下划线分隔单词(摘自http://geosoft.no/development/javastyle.html) 对于基本类型(例如int或字符串)可以很好地工作: 但是非原始类型呢?在大多数情况下,我已经看到以下内容: 或单例,实例变量不是大写的。 问题是声明这些类型的变量(如日志和实例)的正确方法是什么? 问题答案