我有一个关于初始化的有趣问题。我有以下代码:
public class ErrorLookupProvider {
private static final ErrorLookupProvider INSTANCE = new ErrorLookupProvider();
private static Map<Long, List<String>> map = new HashMap<Long, List<String>>();
private ErrorLookupProvider() {
init();
}
private void init() {
map.put(123L, ImmutableList.of("abc", "def"));
}
public static ErrorLookupProvider getInstance() {
return INSTANCE;
}
}
现在当我调用ErrorLookupProvider时。getInstance(),我碰到了一个NPE。init()
中的映射未使用新的HashMap
初始化。
如果我将map
的声明更改为final,那么我看到它已初始化。或者,即使我删除static并将其作为私有类变量private-Map
我一直想不通为什么会这样。有人能解释一下这里发生了什么吗?
补充:订单很重要。将静态映射的声明放在实例声明之前。Java编译器在排序方面有点愚蠢。。。
由于映射是静态的,所以它在ErrorLookupProvider
的所有实例中共享。因此,在构造函数中使用它可能是一个错误。如果您创建了多个ErrorLookupProvider,您将多次冗余地添加到地图中。相反,在静态初始值设定项块中初始化它。或者,如果它真的要在ErrorLookupProvider
的实例之间独立,请不要将其设置为静态。
引用http://javapapers.com/core-java/explain-the-final-keyword-in-java/
声明为最终且未初始化的变量称为空白最终变量。空白最终变量强制构造函数初始化它。
这就是为什么当宣布为最终版本时,它会被草签
切换映射和单例实例初始化的顺序。
静态初始化按照在源中遇到的顺序进行。
参见JLS 12.4.2详细初始化程序、步骤6(最终部分)和步骤9(订单部分)。
(单例实现和在ctor中处理静态,另一期。)
问题内容: 我想知道为什么默认情况下C,C ++和Java中的确切静态变量初始化为零?为什么对局部变量不是这样? 问题答案: 为什么要对静态变量进行确定性初始化而对局部变量不进行初始化? 了解如何实现静态变量。 它们的内存在链接时分配,并且它们的初始值也在链接时提供。 没有运行时开销。 另一方面,用于局部变量的内存是在运行时分配的。堆栈必须增长。你不知道以前在那里。如果需要,可以清除该内存(将其清
问题内容: 我想知道静态变量何时初始化为其默认值。加载类时,先创建(分配)静态变量,然后执行静态初始化程序和声明中的初始化是否正确?在什么时候给出默认值?这导致前向参考的问题。 另外,如果你可以参考“ 为什么没有及时初始化静态字段?”这一问题进行解释,尤其是Kevin Brock在同一网站上给出的答案。我不明白第三点。 问题答案: 从请参阅Java静态变量方法: 它是一个属于类而不属于对象(实例)
我正在经历对我来说毫无意义的奇怪行为。以下程序(我试图将其简化为最小的示例)因而崩溃,因为为: 我希望它打印: 但是如果(可以通过取消对main方法的第一行的注释或对以下两行重新排序来完成),程序将正确终止。 我怀疑这个问题与Java类初始化顺序有关,但我在相关JLS部分中找不到任何解释。 所以,我的问题是:这到底是怎么回事?这是某种虫子还是我错过了什么? 我的JDK版本是1.8.0_111
问题内容: 如何在Java中初始化类的私有静态成员。 尝试以下操作: 但是在创建类A的第二个对象然后调用f1()时,我得到了空指针异常。 问题答案: 初始化静态成员的首选方法是(如上所述) 或者对于更复杂的初始化代码,您可以使用静态初始化程序块:
问题内容: 我有以下代码: 这给了我以下错误: 解析错误:语法错误,在第19行的/home/user/Sites/site/registration/inc/registration.class.inc中出现意外的’(’,期待’)’ 所以,我想我做错了什么…但是如果不那样做怎么办?如果我用常规字符串更改mktime内容,它将起作用。所以,我知道我能做到这一点 的那种 像.. 有人有指针吗? 问题答
问题内容: 我想知道静态变量(在类中)何时出现在图片中(初始化)?是在实例构造函数首次调用之后还是在类加载之后?什么时候加载类? 问题答案: 哦,那很复杂。这取决于是否设置了标志,而标志(在C#中)又取决于是否有静态构造函数。更糟的是;在.NET 4中, 我相信 行为发生了变化,使其比以前更加“懒惰”。 坦白说,我不会在此处编写任何特定行为的代码。简单:只要您使用常规代码访问静态字段,它们就会在尝