簡體   English   中英

在Java中保存大型靜態Typesafe字典的優雅方法-或避免代碼太大

[英]Elegant way of holding large static typesafe dictionary in java - or avoiding code too large

基本上,我想擁有一些字典,它比傳統的#define指令摘要。

我有一個舊的頭文件,其中包含6000多個定義,用作標志參數和某些函數,這些定義表示一種類型的實體parameter

在C我有

  GetParameter(... , T_CTITLE, ...); 

在Java中,我想打電話給

  Connector.getParameter(Parameter.CTITLE, ...); 

Parameter將封裝與從庫獲取參數相關的所有邏輯。

參數實例會自動從標頭中提取並轉換為Java代碼,但問題是Parameter類變得太大-即我得到的code too large編譯錯誤(請強調一下:有6000多個參數)。

而且我很高興以使IDE能夠使用自動補全的方式來進行這種抽象,並且會厭惡將參數對象存儲在HashMap想法。

編輯:通過以下方式定義參數類:

public Parameter{
    /** logic **/
    public static final Parameter<T> parameter1 = new Parameter<T>("NAME", "T", 0xAAB);
    ...
    public static final Parameter<T> parameter6000 = new Parameter<T>("FOO", "T", 0xZZZ);
}

一個明顯的技巧是要么划分成一個大的繼承鏈,要么更好地划分成多個接口(不需要public static final噪音),然后用一個接口來繼承它們。

您可以通過減小創建代碼來節省空間。 代替:

new Parameter<T>("NAME", "T", 0xAAB)

極簡主義的方法是:

parameter("NAME T AAB")

有關限制的詳細信息,請參見JVM Spec(第二版)的4.10節 要查看編​​譯后的代碼是什么樣子,請使用javap -c

也許我不太了解您要正確執行的操作,但這對我來說似乎是枚舉的完美用法。 由於您可以向Enums添加函數,因此只要您的Java版本足夠新(1.5+),它們就可以執行您想要的操作。 他們也序列化!

是的,盡管列表很大,但它可以自動完成。

我不知道Enum的大小是否有限制,但是您可以找到答案。

例如:

public enum Parameter {
    NAME("Pending", "T", 0xAAB), FOO("Foo", "T", 0x1FC);

    private final String displayValue;
    private final char myChar;
    private final int someNum;

    private Parameter(String display, char c, int num) {
        this.displayValue = display;
        this.myChar = c;
        this.someNum = num;
    }

    public String getDisplayValue() {
        return displayValue;
    }

    public char getMyChar() {
        return myChar;
    }

    public int getSomeNum() {
        return someNum;
    }
}

現在,這使您可以執行所需的操作。 例如:

System.out.println("Hi, the value is " + Parameter.NAME.getSomeNum());

由於它們在運行時不會更改(畢竟#DEFINE不能更改),因此ENUM應該可以滿足要求。

至於純大小,您可能應該嘗試對它們進行略微分類,然后將它們放在幾個Enum組中。

這使您能夠關聯元數據(數字),自動完成,==等。

基本上,我認為多接口方法是必經之路。 這就是我構造該解決方案的方式; 我不知道Parameter構造函數的第二個參數是什么意思,所以我忽略了它。

在... / com / yourcompany / legacydefines / Parameter.java中:

package com.yourcompany.legacydefines;

public class Parameter<T> {
  private final String name;
  private final T val;

  private Parameter(String name, T val) {
    this.val = val;
    this.name = name;
  }

  public static <T> Parameter<T> newParameter(String name, T val) {
    return new Parameter<T>(name, val);
  }

  // then, standard getters for "name" and "val"
}

在... / com / yourcompany / legacydefines / Parameters1.java中:

package com.yourcompany.legacydefines;

import static com.yourcompany.legacydefines.Parameter.newParameter;

interface Parameters1 {
  public static Parameter<String> Parameter0001 = newParameter("ABC", "ABCVAL");
  // ...
  public static Parameter<Integer> Parameter0999 = newParameter("FOO", 0xABCD);
}

在... / com / yourcompany / legacydefines / Parameters2.java中:

package com.yourcompany.legacydefines;

import static com.yourcompany.legacydefines.Parameter.newParameter;

interface Parameters2 {
  public static Parameter<String> Parameter1001 = newParameter("DEF", "DEFVAL");
  // ...
  public static Parameter<Integer> Parameter1999 = newParameter("BAR", 0x1002);
}

(依此類推)

在... / com / yourcompany / legacydefines / Parameters.java中:

package com.yourcompany.legacydefines;

interface Parameters extends Parameters1, Parameters2, Parameters3, Parameters4,
                             Parameters5, Parameters6, Parameters7 {}

然后,在其他代碼中只需使用Parameters.Parameter4562

在Tom Hawtin的帖子中進行擴展,考慮使用JSON編碼結構。

或者更好的是,與其將參數硬編碼到Java代碼中,不如將它們放入XML或JSON文件(或屬性文件)中,然后將其吸收到最終生成的任何JAR文件中。

我想這就是你想要的。 我猜想,“ T”是類型,您想使用泛型,以便用戶不必強制轉換#define值:

public class Parameter<T> {

    public final static Parameter<String> NAME = new Parameter<String>("hello");
    // .. 5998 more declarations
    public final static Parameter<Integer> FOO = new Parameter<Integer>(0xff0b);


    private T value;
    private Parameter(T value) {
        this.value = value;
    }
    public T getValue() {
        return value;
    }   
}

要訪問參數,只需調用:

String value = Parameter.NAME.getValue();

java常量等於#defines名稱,泛型反映了類型,因此我們只需要將值傳遞給構造函數即可。 代碼完成正常:)

暫無
暫無

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

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