Java 如何帮助Netbeans设计器加载使用hashmap的枚举反向查找的JPanel-s?

Java 如何帮助Netbeans设计器加载使用hashmap的枚举反向查找的JPanel-s?,java,enums,hashmap,netbeans-8,designer,Java,Enums,Hashmap,Netbeans 8,Designer,当我在写这个问题的时候,我找到了问题的根源,这已经成为一个问题。尽管如此,我还是决定发布它,因为它让我们办公室的每个人都感到困惑,我在谷歌或stackoverflow搜索中找不到任何有用的东西。这是一个很好的例子,一旦你提出了正确的问题,你就会看到光明 虽然标题听起来很复杂,但这是一个似乎没有答案的简单问题。这一部分的中心是一个枚举: 状态 public enum Status { INVALID ( "INVALID" ), ISSU

当我在写这个问题的时候,我找到了问题的根源,这已经成为一个问题。尽管如此,我还是决定发布它,因为它让我们办公室的每个人都感到困惑,我在谷歌或stackoverflow搜索中找不到任何有用的东西。这是一个很好的例子,一旦你提出了正确的问题,你就会看到光明

虽然标题听起来很复杂,但这是一个似乎没有答案的简单问题。这一部分的中心是一个
枚举

状态

    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)
  ... ... ...
通过一个消除过程——注释掉不相关的代码——我发现一旦注释掉状态枚举中的HashMap
put()
调用,表单就会加载

“那很有趣。”我说。这看起来像是
put()
的副作用。在away中,它是一个很小的错误,在没有JPanel和Netbeans的情况下,它很快在命令行中给了我同样的错误

错误是由我尝试从枚举构造函数中使用哈希映射引起的。它不会像写的那样工作


因此,我将标题改为直指真正的问题——实际上,就是如何使用HashMap对枚举进行反向查找?

问题来自于如何在
状态
枚举中声明HashMap,因为枚举是如何初始化的

Java枚举中的第一件事必须是值列表,这里是:“无效”、“已发布”和“已取消”。每个人都需要知道的下一件事是,在对象创建(类或枚举)过程中,有一个秘密的Java阶段首先运行。Init是哑的,它通过先到先得的声明性代码线性运行

枚举的前3个x语句调用构造函数——这意味着该语句:

    private final static  Map<String,Status>  displayMap = new HashMap( 4 );
然后一切都很顺利

警告

不要在displayMap声明中分配
null
,这会适得其反:

  • if(null==displayMap){…}
    块在第一次调用枚举构造函数期间成功地分配了HashMap
  • 处理完所有枚举值声明后
  • Init将调用声明变量的任何初始值
  • 如果
    displayMap=null时,它将使用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 );
            }
        }