Доступ к другим перечислениям в конструкторе перечисления - PullRequest
4 голосов
/ 25 февраля 2011

Мне нужно что-то вроде следующего

enum EE {
    A("anything"),
    B("beta"),
    ...
    Z("zulu"),
    ALL,
    ;

    EE(String s) {
        this.s = s;
    }
    EE() {
        String s = "";
        for (EE ee : values()) { // PROBLEM HERE
            if (ee != ALL) s += " " + ee.s;
        }
        this.s = s;
    }
}

При создании ALL Я хотел бы получить доступ к другим членам enum. Выше не работает, потому что values() возвращает null на данный момент. Использование A, B, ..., Z явно не компилируется. Я прекрасно понимаю, почему возникает проблема с куриным яйцом, но я ищу хороший обходной путь.

И нет, удаление ALL из EE не вариант.

Ответы [ 4 ]

5 голосов
/ 25 февраля 2011

Будет ли это работать для вас? :

enum EE {
    A("anything"),
    B("beta"),
    ...
    Z("zulu"),
    ALL,
    ;

    String s = null;

    EE(String s) {
        this.s = s;
    }

    EE() {
    }

    private void initS() {
        String s = "";
        for (EE ee : values()) { 
            if (ee != ALL) s += " " + ee.s;
        }  

        this.s = s;
    }

    public String getS() {
       if ( this.s == null )  { // assume we are ALL and initialize
         initS();
       }

       return this.s;
    }
}

Статический инициализатор может быть чище.

public enum EE {
    A("anything"),
    B("beta"),
    Z("zulu"),
    ALL
    ;

    static {
        String s = "";
        for (EE ee : values()) {
            if ( ee != ALL ) s += ee + " ";
        }

        ALL.s = s.trim();
    }

    String s = null;

    EE(String s) {
        this.s = s;
    }

    EE() {
    }
}
3 голосов
/ 25 февраля 2011

У вас может быть статический StringBuilder, к которому каждая константа перечисления добавляет свое значение в конструкторе, тогда в конструкторе по умолчанию просто установите строку перечисления в значение StringBuilder.

Обратите внимание, что Java не позволит вам получать доступ к статическим переменным напрямую из конструктора enum (по уважительной причине!), Поэтому вам придется выполнить грязную работу в другом методе, а затем вызвать его из конструктора.

Чтобы это работало, вы должны убедиться, что ALL объявлен последним.

Как заявление об отказе от ответственности, хотя это действительно ужасный обходной путь, и если вы вообще сможете, я бы посоветовал вам изучить другие возможности здесь!

1 голос
/ 23 декабря 2011

Одним из лучших способов было бы использование enum polymorphism technique:

public enum EE {
    A("anything"), B("beta"), Z("zulu"), ALL {

        @Override
        public String getS() {
            if (super.s == null) {
                String s = "";
                for (EE ee : values()) {
                    if (ee != ALL) {
                        s += " " + ee.s;
                    }
                }
            }
            return s;
        }
    },
    ;

    private String s;

    EE(String s) {
        this.s = s;
    }

    EE() {
        this.s = null;
    }

    public String getS() {
        return this.s;
    }
}

Тестовый класс:

public class TestEE {

    public static void main(String[] args) {
        for (EE ee : EE.values()) {
            System.out.println(ee.name() + ": " + ee.getS());
        }
    }
}

См. Также:

0 голосов
/ 25 февраля 2011

почему вы не можете удалить все?

рассмотрите возможность использования EnumSet , это даст вам любую комбинацию EE.

import java.util.*;
enum EE {
    A("anything"), B("beta"), Z("zulu");
    EE(String s) {
        this.s = s;
    }
    static Set<EE> all=EnumSet.allOf(EE.class);
    final String s;
}
...