【问题标题】:Private static final variable inside an enum枚举中的私有静态最终变量
【发布时间】:2012-03-05 10:23:24
【问题描述】:

我正在尝试在枚举中创建一个私有静态最终变量,但我不断收到编译错误。有谁知道如何解决这个问题?

这一行有多个标记

  • 语法错误,插入“标识符”以完成 EnumConstantHeaderName
  • 语法错误,插入“}”以完成 EnumBody
class Foo {
  ...

  public enum MyEnum {
    private static final String MY_STRING = "a string I use in a constructor";
    private static final String MY_OTHER_STRING = "a string I use in another constructor";      

    MyEnumType(1, MY_STRING),
    MyEnumType2(2, MY_STRING),
    MyEnumType3(3, MY_OTHER_STRING);

    MyEnum(int num, String str) {
      ...
    } 
  }
 ...
}

【问题讨论】:

    标签: java enums compiler-errors


    【解决方案1】:

    枚举常量需要是枚举中的第一个元素。可编译的代码版本:

    class Foo {
    
        public enum MyEnum {
            MyEnumType, MyEnumType2;
    
            public String bar() {
                return MY_STRING;
            }
    
            public String bar2() {
                return MY_STRING + "2";
            }
    
            private static final String MY_STRING = "a string I reuse in the enum";
        }
    }
    

    * 编辑 *

    根据您对原始问题所做的修改,我知道您要做什么。不,不可能在枚举定义本身中声明的枚举文字声明中使用常量。这是因为文字声明必须是枚举中的第一个元素。这是 Java 语言规范规定的。两件快速的事情:

    1. 您正在使用private static final Strings。这给你 绝对比使用字符串文字没有任何好处, 这将解决问题。
    2. 如果您想声明可重用的常量 (public static final Strings),那么您需要在枚举之外这样做。

    或者,您可以将您的枚举声明为为您定义 private static final String 的类的嵌套元素。

    一些伪代码:

    public class Foo {
        public static enum MyEnum {
            MyEnumType(0, MY_STRING), MyEnumType2(1, "Hello");
    
            private int ordinal;
            private String value;
    
            MyEnum(int ordinal, String value) {
                this.ordinal = ordinal;
                this.value = value;
            }
    
            public int getOrdinal() {
                return ordinal;
            }
    
            public String getValue() {
                return value;
            }
    
            public void setOrdinal(int ordinal) {
                this.ordinal = ordinal;
            }
    
            public void setValue(String value) {
                this.value = value;
            }
        }
    
        private static final String MY_STRING = "a string I reuse in the enum";
    }
    

    【讨论】:

    • 约定说要把你的字段放在你的方法上。
    • 我实际上是在构造函数中使用字符串。
    • Tom - 你所说的“把你的字段放在你的方法上”是什么意思?
    【解决方案2】:

    有可能,你只需要直接引用变量。

    class Foo {
      ...
    
      public enum MyEnum {
    
        MyEnumType(1, MyEnum.MY_STRING),
        MyEnumType2(2, MyEnum.MY_STRING),
        MyEnumType3(3, MyEnum.MY_OTHER_STRING);
    
        MyEnum(int num, String str) {
          ...
        }
    
         private static final String MY_STRING = "a string I use in a constructor";
         private static final String MY_OTHER_STRING = "a string I use in another constructor";  
      }
     ...
    }
    

    【讨论】:

    • 太棒了! (而且很奇怪)
    • 我得到了一个非法的前向引用,但我正在传递已编译的模式。不过,嵌套在枚举中的接口起到了作用。
    • 似乎编译(奇怪)但在运行时我得到java.lang.NoClassDefFoundError: Could not initialize class
    • 编译但给出运行时异常
    【解决方案3】:

    接口可以使用:

    class Foo {
      ...
    
      private interface MyEnumConstants {
        static final String MY_STRING = "a string I use in a constructor";
        static final String MY_OTHER_STRING = "a string I use in another constructor";      
      }
    
      public enum MyEnum implements MyEnumConstants {
        MyEnumType(1, MY_STRING),
        MyEnumType2(2, MY_STRING),
        MyEnumType3(3, MY_OTHER_STRING);
    
        MyEnum(int num, String str) {
          ...
        } 
      }
     ...
    }
    

    【讨论】:

    • 如果您不想在另一个类中同时包含这两个接口,您可以将接口嵌套在枚举中。
    【解决方案4】:

    你可以像这样在枚举中声明接口

    enum MyEnum {
        MyEnumType(1, EnumConstants.MY_STRING), 
        MyEnumType2(2, EnumConstants.MY_STRING), 
        MyEnumType3(3, EnumConstants.MY_OTHER_STRING);
    
        MyEnum(int num, String str) {
    
        }
    
        interface EnumConstants {
            static final String MY_STRING = "a string I use in a constructor";
            static final String MY_OTHER_STRING = "a string I use in another constructor";
        }
    }
    

    【讨论】:

      【解决方案5】:

      对先前答案的反对意见是 1)有些不起作用,2)有些没有真正的常量,3)有些需要嵌入或额外的类。这样做怎么样?

      public class Constants {
          public static final double EQUATORIALRADIUS = 6378137.0;
      }
      
      public enum Planet {
          EARTH (Constants.EQUATORIALRADIUS),
      

      “但是!”,你说,“还有一门课!” 不,您只需在编译之后和 dexing 或压缩到 jar 之前删除 Constants.class 文件。 或者你可以Proguard它。在任何情况下,您都可以使用 apktool 验证在任何地方都没有对 Constants 类的引用。所有的常量都是真正的常量,并且与 smali 一致。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        相关资源
        最近更新 更多