2010-05-19 72 views
1

我有一些處理固定長度數據記錄的代碼。我用java枚舉定義了記錄結構。我把它簡化成最簡單的例子來說明我現在必須跳過的框架才能訪問枚舉中的靜態變量。有沒有更好的方法來獲得我忽略的這個變量?如果您編譯並運行代碼,它會將每個字符串轉換爲XML塊。我已經手動完成了XML,因此該示例更簡單,但我的真實代碼使用Java DOM。如何在沒有類實例的情況下訪問枚舉類中的靜態變量?

編輯:我已經更新了一個更完整的例子,我認爲更好地顯示了我想要做的事。

class EnumTest 
{ 
    public static void main(String args[]) 
    { 
     System.out.println(parse("ABC", RecordType1.class)); 
     System.out.println(parse("ABCDEF", RecordType2.class)); 
    } 

    private interface RecordLayout { 
     public int length(); 
    } 

    private enum RecordType1 implements RecordLayout { 
     FIELD1  (2), 
     FIELD2  (1), 
     ; 
     private int length; 
     private RecordType1(int length) { this.length = length; } 
     public int length() { return length; } 

     public static int RECORD_LEN = 3; 
    } 

    private enum RecordType2 implements RecordLayout { 
     FIELD1  (5), 
     FIELD2  (1), 
     ; 
     private int length; 
     private RecordType2(int length) { this.length = length; } 
     public int length() { return length; } 

     public static int RECORD_LEN = 6; 
    } 

    private static <E extends Enum<E> & RecordLayout> String parse(String data, Class<E> record) { 

     // ugly hack to get at RECORD_LEN... 
     int len = 0; 
     try { 
      len = record.getField("RECORD_LEN").getInt(record); 
     } 
     catch (Exception e) { System.out.println(e); } 

     String results = "<RECORD length=\"" + len + "\">\n"; 
     int curPos = 0; 
     for (E field: record.getEnumConstants()) { 
      int endPos = curPos + field.length(); 
      results += " <" + field.toString() + ">" 
        + data.substring(curPos, endPos) 
        + "</" + field.toString() + ">\n"; 
      curPos = endPos; 
     } 
     results += "</RECORD>\n"; 
     return results; 
    } 
} 
+0

我還沒有看到一個原因,他們是靜態的,也可以是實例級和最終 – 2010-05-19 22:16:50

回答

1

這個代碼在Java 8中怎麼樣?

// Java 8 
public class EnumTest { 
    public static void main(String args[]) { 
     System.out.println(parse("ABC", RecordType1.class)); 
     System.out.println(parse("ABCDEF", RecordType2.class)); 
    } 

    private interface RecordLayout { 
     public int length(); 

     public static <E extends Enum<E> & RecordLayout> int getTotalLength(Class<E> e) { 
      int total = 0; 
      for (E e1 : e.getEnumConstants()) { 
       total += e1.length(); 
      } 
      return total; 
     } 
    } 

    private enum RecordType1 implements RecordLayout { 
     FIELD1(2), 
     FIELD2(1),; 
     private int length; 

     private RecordType1(int length) { 
      this.length = length; 
     } 

     public int length() { 
      return length; 
     } 
    } 

    private enum RecordType2 implements RecordLayout { 
     FIELD1(5), 
     FIELD2(1),; 
     private int length; 

     private RecordType2(int length) { 
      this.length = length; 
     } 

     public int length() { 
      return length; 
     } 
    } 

    private static <E extends Enum<E> & RecordLayout> String parse(String data, Class<E> record) { 
     int len = RecordLayout.getTotalLength(record); 
     String results = "<RECORD length=\"" + len + "\">\n"; 
     int curPos = 0; 
     for (E field : record.getEnumConstants()) { 
      int endPos = curPos + field.length(); 
      results += " <" + field.toString() + ">" 
        + data.substring(curPos, endPos) 
        + "</" + field.toString() + ">\n"; 
      curPos = endPos; 
     } 
     results += "</RECORD>\n"; 
     return results; 
    } 
} 
1

RecordType1.LEN不工作?

我現在手邊沒有Java環境,所以我準備從我的臉上抹蛋,但因爲enum Foo等於class Foo extends Enum<Foo>我看不到爲什麼你不能只訪問靜態成員標準的方式。

編輯:如果你想動態地訪問靜態成員,那麼這是不會工作的,因爲你有基於類而不是實例訪問靜態成員,這就是要點。你或許應該做這樣的事情,而不是,因爲如果根據實例的亞型行爲的變化,這是正是的那種東西的接口是:

class EnumTest 
{ 

    private interface RecordLayout { 
     public int length(); 
     public int staticLength(); // give this a more meaningful name 
    } 

    private enum RecordType1 implements RecordLayout { 
     ... 

     public static int LEN = 3; 
     public int staticLength() { 
      return LEN; 
     } 
    } 

    private enum RecordType2 implements RecordLayout { 
     ... 

     public static int LEN = 5; 
     public int staticLength() { 
      return LEN; 
     } 
    } 

    ... 

    private static String parse(String data, RecordLayout record) { 
     int len = record.getStaticLength(); 
     System.out.println(len); 

     ... 
    } 
} 
+0

解析方法,就是要通用的,所以它可以處理實現了RecordLayout接口的任何枚舉。在我的實際代碼中,有許多這樣的枚舉。如果我將RecordType1.LEN放入我的解析方法中,那麼如果我使用RecordType2.class作爲參數調用它,那將是錯誤的。 – krick 2010-05-19 21:11:51

+0

在這種情況下,您必須在RecordLayout接口中添加另一個方法,因爲泛型類型參數在編譯時只不過是語法糖。 在運行時,幾乎在所有情況下都消失。 – 2010-05-19 21:14:03

+1

然後問題是你正在傳遞一個類(記錄)而不是記錄的實例。如果你傳入一個記錄的實例,你可以調用:record.length()。 – staticman 2010-05-19 21:15:19

0

只要你是裏面的EnumTest類,你可以通過簡單的寫訪問LEN領域:

int len = RecordType1.LEN; 

從外面看,它仍然是困難的。

+0

查看我的評論Andrzej。 – krick 2010-05-19 21:14:21

相關問題