簡體   English   中英

使用私有靜態成員在Java中構造枚舉

[英]Use private static member to construct enum in java

考慮以下枚舉構造:

public enum MyEnum {
    ENUM_A(TYPE1), ENUM_B(TYPE2), ENUM_C(TYPE1), ENUM_D(TYPE1);
    private static final String TYPE1 = "I am type 1";
    private static final String TYPE2 = "This is type 2";
    private final String type;
    private MyEnum(String type) {
        this.type = type;
    }
    public String getType() {
        return type;
    }
}

上面的代碼無法編譯,因為編譯器在抱怨illegal forward reference 我有點理解為什么常量是枚舉之后定義的。

但是 ,不能將常量移動到枚舉定義之上/之前,這就是枚舉限制/設計,即枚舉定義必須是枚舉類中的第一件事。

現在,如果代碼更改為:

public enum MyEnum {
    ENUM_A(MyEnum.TYPE1), ENUM_B(MyEnum.TYPE2), ENUM_C(MyEnum.TYPE1), ENUM_D(MyEnum.TYPE1);
    private static final String TYPE1 = "I am type 1";
    private static final String TYPE2 = "This is type 2";
    private final String type;
    private MyEnum(String type) {
        this.type = type;
    }
    public String getType() {
        return type;
    }
}

然后它似乎起作用。

我的問題是:即使編譯后,更改后的代碼還會帶來任何潛在問題嗎? 為什么更改可以解決編譯器檢查的問題? 這是一種標准方法還是一種繞過將來可能會解決的編譯器檢查的方法?

這是一個完全可以接受的解決方案,除了多余的雜物之外,我沒有其他缺點。

如果要消除混亂,可以使用interface可以容納恆定值的事實。 對於某些編碼人員來說,這可能會打破最不驚奇的原則,但是我會在我的代碼中接受它。

private interface MyConstants {
    String TYPE1 = "I am type 1";
    String TYPE2 = "This is type 2";
}

public enum MyEnum implements MyConstants{
    ENUM_A(TYPE1), ENUM_B(TYPE2), ENUM_C(TYPE1), ENUM_D(TYPE1);
    private final String type;
    private MyEnum(String type) {
        this.type = type;
    }
    public String getType() {
        return type;
    }
}

是的,這有點問題。

通過規避不使用尚未聲明的字段的限制(通過引用聲明了這些靜態字段的類,該類可能不是當前類,因此繞過了編譯器對已聲明此字段的驗證),您正在使用這些字段存在之前。

在您的示例中,它運行良好,因為您的字段碰巧是常量:它們是聲明為final的String文字。 因此,編譯器會在編譯時知道它們的值,並用已知的MyEnum.TYPE1常量值替換MyEnum.TYPE1。

如果您使字段變得非恆定,它將停止工作,但是它將仍然編譯並且僅在運行時提供不需要的結果。 例如,嘗試:

private static final String TYPE1 = new String("I am type 1");

不再是常數=>不再起作用。

另外,您可以將枚舉放入常規類中,並將常量聲明為與枚舉並排的類成員。

public class ConstantTypes {

   private static String type1 = "type 1"
   private static String type2 = "type 2"

   public enum Types {
      A(type1) {},
      B(type1) {},
      C(type2) {},
      D(type2) {};
      private final String type;
      private Types(String typ) {
          type = typ;
      }
      public String getType() { return type; }
   }
}

編輯:要直接回答您的問題,在第二個代碼示例中,您本身並不完全在“解決編譯器檢查”。 您在此處以“靜態方式”訪問靜態值,而在第一個示例中則不是。 我的第二個示例沒有任何潛在的問題(也許可讀性除外),代碼可以編譯,這很不錯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM