如何在没有类实例的情况下访问枚举类中的静态变量?

时间:2010-05-19 20:57:47

标签: java generics static enums field

我有一些处理固定长度数据记录的代码。我已经使用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;
    }
}

3 个答案:

答案 0 :(得分: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);

        ...
    }
}

答案 1 :(得分: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;
    }
}

答案 2 :(得分:0)

只要您在EnumTest课程内,只需写下以下内容即可访问LEN字段:

int len = RecordType1.LEN;

从外面看,它仍然很难。