Как получить доступ к статическим переменным в классе enum без экземпляра класса? - PullRequest
1 голос
/ 20 мая 2010

У меня есть код, который обрабатывает записи данных фиксированной длины. Я определил структуры записей, используя перечисления 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 ]

1 голос
/ 09 марта 2014

Как насчет этого кода в 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 голос
/ 20 мая 2010

Не работает 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 голосов
/ 20 мая 2010

Пока вы находитесь внутри класса EnumTest, вы можете получить доступ к полю LEN, просто написав:

int len = RecordType1.LEN;

Снаружи это все еще сложно.

...