簡體   English   中英

如何在 Java 中獲取 static class 成員的枚舉?

[英]How to get an enum of static class members in Java?

我有一個 Java class(我不控制也不能修改)它有大量的 static String 成員。 我怎樣才能將這些作為枚舉(為了編碼方便)?

例如我有:

public class ClassWithStaticMembers {
  public static String ONE = "one";
  public static String TWO = "dos";
}

...我想從中得出以下結論:

public enum NUMBERS {
  ONE,
  TWO
}

這是可能的,有反射或其他方式嗎?

(假設我不太了解 Java,並且我有 100 多個值,所以重復每個值是痛苦的,也是不可取的(以防以后添加更多值)。而且我不需要 class 中的實際值(“一個”和上面的“dos”))。

為簡單起見:枚舉是靜態描述的,因此不可能通過反射創建它。

您仍然可以創建一個枚舉來包裝您的常量,並且可以選擇進行單元測試(使用反射)以確保您的枚舉是完整的。

public enum NumbersEnumeration {
  ONE(ClassWithStaticMembers.ONE),
  TWO(ClassWithStaticMembers.TWO);
  private static final String name;
  public String getName(){return name};
  public NumbersEnumeration(String name){this.name=name;}
}


public class NumbersEnumerationTest{

  @Test
  public void checkEnumComplete() throws Exception{
    var fields = List.of(ClassWithStaticMembers.class.getDeclaredFields());
    for( var field:fields){
      Assertions.assertNotNull(NumbersEnumeration.valueof(field.getName());
    }
  }
}

(反射可能存在編譯問題,但你明白了)

您可以使用Class.getDeclaredFields()獲取表示由 class 定義的字段的java.lang.reflect.Field實例,並過濾掉標記為static的字段並訪問它們的值。

問題是getDeclaredFields()保證它返回的數組將以任何特定方式排序。 這是文檔中的引述:

返回數組中的元素未排序未按任何特定順序排列

因此,如果您正在考慮根據聲明的順序自動關聯 static 字段和枚舉成員,那是行不通的,反射 API 在這里幫不上忙。

我建議引入一個單獨的實用程序類,它將包裝一個Map關聯字符串值和枚舉常量。

public class NumbersUtils {
    public static final Map<String, Numbers> NUMBERS = Map.ofEntries(
        Map.entry("one", Numbers.ONE),
        Map.entry("dos", Numbers.TWO),
        ...
    );
    
    private NumbersUtils() {} // utility classes are not meant to be instantiated

    public static Numbers toNumber(String str) {
        if (!NUMBERS.containsKey(str)) throw new IllegalStateException(); // or remove this line if you don's want to throw in such case, method would return null instead
        
        return NUMBERS.get(str);
    }
}

即使您有可能修改枚舉,最好將此邏輯保留在枚舉之外,而在枚舉內您可以引入一個委托給NumbersUtils.toNumber()的方法

旁注:

  • 如果代碼中的這些 static 字符串和枚舉在不同語言中表示相同的東西,並且它們旨在促進應用程序的國際化,那么保留硬編碼字符串您可能希望熟悉正確的 I18N 技術(通過properties文件和ResourceBundle包)。 本教程將給出關於該主題的總體思路。

  • 在編寫代碼時盡量遵守[Java 語言命名約定][約定]。 名稱枚舉(以及類和接口)應該更新為大寫。

暫無
暫無

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

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