2010-05-19 10 views
1

고정 길이 데이터 레코드를 처리하는 코드가 있습니다. 나는 자바 enum을 사용하여 레코드 구조를 정의했다. 열거 형 내부의 정적 변수에 액세스하기 위해 현재 점프해야하는 농구를 설명하기 위해 가능한 가장 간단한 예제를 끓여 냈습니다. 이 변수를 간과 할 수있는 더 좋은 방법이 있습니까? 코드를 컴파일하고 실행하면 각 문자열을 XML 청크로 변환합니다. XML을 수동으로 처리 했으므로 예제가 더 간단하지만 실제 코드는 Java DOM을 사용합니다.클래스 인스턴스가없는 enum 클래스의 정적 변수에 어떻게 액세스합니까?

EDIT : 코드를보다 완벽한 예제로 업데이트하여 내가하려는 것을 더 잘 보여줄 것으로 생각합니다.

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

난 아직도 이유를 보지 않는다, 그들은 인스턴스 수준과 최종 –

답변

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 Fooclass Foo extends Enum<Foo>과 같기 때문에 왜 정적 멤버에 액세스 할 수 없는지 알 수 없습니다. 표준 방식.

편집 : 정적 멤버에 동적으로 액세스하려면 이 있으면 인스턴스가 아닌 클래스를 기반으로 정적 멤버에 액세스 할 수 있습니다. 만큼 당신이 EnumTest 내부에로

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 인터페이스를 구현하는 열거를 처리 할 수 ​​있도록 포괄적으로 의미가 될 수 있습니다. 내 실제 코드에는 많은 enum이 있습니다. 필자의 구문 분석 메소드에 RecordType1.LEN을 넣으면 RecordType2.class를 매개 변수로 호출하면 잘못 될 것입니다. – krick

+0

그런 경우, 제네릭 형식 매개 변수가 컴파일 타임에 문법적 설탕보다 조금 더 많으므로 다른 메서드를'RecordLayout' 인터페이스에 추가해야합니다. 런타임에는 거의 모든 경우에서 사라집니다. –

+1

그러면 문제는 레코드의 인스턴스가 아닌 클래스 (레코드)에 전달한다는 것입니다. 레코드의 인스턴스를 전달한 경우 record.length()를 호출 할 수 있습니다. – staticman

0

: 당신은 아마 동작 변경은 인스턴스의 하위 유형에 따라 경우 때문에, 그 인터페이스를위한 일의 정확히 종류의, 대신 같은 것을 할해야 클래스, 당신은 간단하게 작성하여 LEN 필드에 액세스 할 수 있습니다

int len = RecordType1.LEN; 

을 외부에서 여전히 어렵다.

+0

Andrzej에 대한 내 의견보기. – krick

관련 문제