我有一个有趣的初始化问题。我有以下代码:加载类时未初始化静态变量
现在,当我打电话ErrorLookupProvider.getInstance()
,我打了一个NPE。 init()
中的地图未使用新的HashMap
进行初始化。
如果我将map
的声明更改为final,那么我会看到它已初始化。或者,即使我删除静态并将其设置为私有类变量private Map<.....>
也可以。
我一直无法弄清楚为什么会发生这种情况。有人可以解释这里发生了什么吗?
我有一个有趣的初始化问题。我有以下代码:加载类时未初始化静态变量
现在,当我打电话ErrorLookupProvider.getInstance()
,我打了一个NPE。 init()
中的地图未使用新的HashMap
进行初始化。
如果我将map
的声明更改为final,那么我会看到它已初始化。或者,即使我删除静态并将其设置为私有类变量private Map<.....>
也可以。
我一直无法弄清楚为什么会发生这种情况。有人可以解释这里发生了什么吗?
从http://javapapers.com/core-java/explain-the-final-keyword-in-java/
引用被声明为final和未初始化叫做空白最终变量的变量。一个空白的final变量强制构造函数初始化它。
这就是为什么声明为final,当它被初始化
它甚至是有效的调用私人静态最终ErrorLookupProvider INSTANCE = new ErrorLookupProvider(); 类的初始化首先是静态变量,静态块,成员变量和构造函数。但是,在这种情况下,调用构造函数来初始化静态变量甚至是有效的吗? – Sudoer
是的,那很好。对你的代码只是一个小小的评论,你可以用它作为你的HashMap的声明这个 private static Map
NO NO NO,当声明为final时,如果变量未由您初始化,构造函数将强制它初始化 – MaVRoSCy
新增:订购事宜。在之前将您的静态地图的声明放在INSTANCE的声明中。 Java编译器在订购时有点愚蠢......
由于映射是静态的,因此它在所有ErrorLookupProvider
实例中共享。因此,在构造函数中使用它可能是一个错误。如果您创建多个ErrorLookupProviders,则会多次冗余地添加到地图中。相反,请在静态初始化块中初始化它。或者,如果它确实是要在ErrorLookupProvider
的实例之间独立,请不要将其设为静态。
切换映射和单例实例初始化的顺序。
静态初始化按其在源中遇到的顺序发生。
请参阅JLS 12.4.2 Detailed Initialization Procedure步骤6(final
部分)和9(“订单”部分)。
(单例的实现,并在构造函数静碴,单独的问题。)
哦!这是因为静力学的顺序。如果我先把地图放在地图上,那我想也行。 这导致我问题 - 这甚至允许? private static final ErrorLookupProvider INSTANCE = new ErrorLookupProvider(); 通过排序,我通过调用构造函数初始化我的静态变量。这意味着甚至在变量初始化之前调用构造函数。这个用法不正确吗? Usualy中,init情况如下: 1.静态成员 2.静态块 3.会员瓦尔 4.构造 现在,我想从1跳转到4.如果这是不允许的? – Sudoer
@Sudoer是的,这就是我们所说的 - 顺序重要:)当然它是允许的 - 它的工作原理,不是吗? –
会,即使非长映射键编译? –
我的错误,我错过了123L – Sudoer