Java 如何帮助Netbeans设计器加载使用hashmap的枚举反向查找的JPanel-s?
当我在写这个问题的时候,我找到了问题的根源,这已经成为一个问题。尽管如此,我还是决定发布它,因为它让我们办公室的每个人都感到困惑,我在谷歌或stackoverflow搜索中找不到任何有用的东西。这是一个很好的例子,一旦你提出了正确的问题,你就会看到光明 虽然标题听起来很复杂,但这是一个似乎没有答案的简单问题。这一部分的中心是一个Java 如何帮助Netbeans设计器加载使用hashmap的枚举反向查找的JPanel-s?,java,enums,hashmap,netbeans-8,designer,Java,Enums,Hashmap,Netbeans 8,Designer,当我在写这个问题的时候,我找到了问题的根源,这已经成为一个问题。尽管如此,我还是决定发布它,因为它让我们办公室的每个人都感到困惑,我在谷歌或stackoverflow搜索中找不到任何有用的东西。这是一个很好的例子,一旦你提出了正确的问题,你就会看到光明 虽然标题听起来很复杂,但这是一个似乎没有答案的简单问题。这一部分的中心是一个枚举: 状态 public enum Status { INVALID ( "INVALID" ), ISSU
枚举
:
状态
public enum Status
{
INVALID ( "INVALID" ),
ISSUED ( "Issued" ),
CANCELLED ( "Cancelled");
private final String displayName;
private final static Map<String,Status> displayMap = new HashMap( 4 );
private Status( String display ){
this.displayName = display;
mapDisplayName( this.displayName, this );
}
public String getDisplayName(){
return displayName;
}
public static Status parseString( String statusStr ) {
return displayMap.get( statusStr );
}
private static void mapDisplayName( final String displayName, final Status state ){
displayMap.put( displayName, state );
}
}
public enum Status
{
INVALID ( "INVALID" ),
ISSUED ( "Issued" ),
CANCELLED ( "Cancelled");
private static Map<String,Status> displayMap;
private Status( String display ){
this.displayName = display;
mapDisplayName( this.displayName, this );
}
:
private static void mapDisplayName( final String displayName, final Status state ){
if( null == displayMap ){
displayMap = new HashMap( 7 );
}
displayMap.put( displayName, state );
}
}
在主JPanel中引用。当我在Netbeans设计器中查看这个JPanelStatus
子面板时,它工作正常。[预览设计
]功能也是如此
但是,当我加载主窗体时,它失败,异常显示初始化失败:
java.lang.NoClassDefFoundError: Could not initialize class au.com.project.State
at au.com.project.client.JPanelStatus.<init>(JPanelStatus.java:35)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
... ... ...
通过一个消除过程——注释掉不相关的代码——我发现一旦注释掉状态枚举中的HashMapput()
调用,表单就会加载
“那很有趣。”我说。这看起来像是put()
的副作用。在away中,它是一个很小的错误,在没有JPanel和Netbeans的情况下,它很快在命令行中给了我同样的错误
错误是由我尝试从枚举构造函数中使用哈希映射引起的。它不会像写的那样工作
因此,我将标题改为直指真正的问题——实际上,就是如何使用HashMap对枚举进行反向查找?问题来自于如何在
状态
枚举中声明HashMap,因为枚举是如何初始化的
Java枚举中的第一件事必须是值列表,这里是:“无效”、“已发布”和“已取消”。每个人都需要知道的下一件事是,在对象创建(类或枚举)过程中,有一个秘密的Java阶段首先运行。Init是哑的,它通过先到先得的声明性代码线性运行
枚举的前3个x语句调用构造函数——这意味着该语句:
private final static Map<String,Status> displayMap = new HashMap( 4 );
然后一切都很顺利
警告:
不要在displayMap声明中分配null
,这会适得其反:
块在第一次调用枚举构造函数期间成功地分配了HashMapif(null==displayMap){…}
- 处理完所有枚举值声明后
- Init将调用声明变量的任何初始值
- 如果
displayMap=null声明code>时,它将使用3个x值替换填充的HashMap,并使用一个新的空HashMap。grrr
- 。。。我觉得HashMap可以更容易地提供多个字符串的反向查找
如果你能做到这一点,它需要在第一个枚举常数之前使用,以避免向前引用。
private final static Map<String,Status> displayMap = new HashMap( 4 );
public enum Status
{
INVALID ( "INVALID" ),
ISSUED ( "Issued" ),
CANCELLED ( "Cancelled");
private static Map<String,Status> displayMap;
private Status( String display ){
this.displayName = display;
mapDisplayName( this.displayName, this );
}
:
private static void mapDisplayName( final String displayName, final Status state ){
if( null == displayMap ){
displayMap = new HashMap( 7 );
}
displayMap.put( displayName, state );
}
}