EnumSet для поддельных перечислений до 1.5? - PullRequest
4 голосов
/ 14 апреля 2009

Недавно я делал много таких

enum Thing {

    /* etc etc */

    static final Set<Thing> allThings = EnumSet.allOf(Thing.class);

}

Я хочу что-то подобное в Java до 1.5, то есть я хочу что-то вроде:

final class Thing {

    private Thing(); // control instances within class

    static final Thing instance0 = new Thing();
    static final Thing instance1 = new Thing();

    static final Set allThings = // ?????
}

Как мне это сделать?

Ответы [ 4 ]

4 голосов
/ 14 апреля 2009

Что насчёт этого:

final class Thing {

  static final Set allThings = new HashSet();

  private Thing() {
      allThings.add(this);
  } // control instances within class

  static final Thing instance0 = new Thing();
  static final Thing instance1 = new Thing();
}
3 голосов
/ 14 апреля 2009

Не было прямого эквивалента в Java до 1.5.

До Java 1.5 было две (синтаксически причудливые) опции, если вы хотели немедленно инициализировать:

static final Set allThings = new HashSet(Arrays.asList(new Object[] {
    instance0, instance1, // etc.
}));

или

static final Set allThings = new HashSet() {{
    add(instance0);
    add(instance1);
    // etc.
}};

У обоих есть свои недостатки. Проще всего сделать статический метод

private static Set all() {
    Set ret = new HashSet();
    ret.add(instance0);
    ret.add(instance1);
    // etc.
}

Вы все еще должны помнить, чтобы добавлять какие-либо новые члены в метод, но его легче читать (для большинства людей).

1 голос
/ 14 апреля 2009

Существует довольно четкая схема определения типов безопасных перечислений в среде, предшествующей Jav5.

Это в основном класс с полями public final static для значений и личным конструктором (или более).

Единственная «сложная» вещь - это получение таких деталей, как правильная сериализация (в основном, путем реализации readResolve()).

Этот совет Javaworld достаточно подробно описывает этот вопрос, а у этого есть что сказать по этому поводу.

0 голосов
/ 14 апреля 2009

В следующем решении каждый класс перечисления расширяет абстрактный базовый класс AbstractEnum и имеет собственный набор всех значений, автоматически генерируемых и сохраняемых в статической карте в базовом классе.

 public abstract class AbstractEnum
  {
    private final static Map/*<Class,Collection<AbstractEnum>>*/ allEnums 
      = new HashMap();

    protected AbstractEnum()
    {
      Collection/*<AbstractEnum>*/ allValues 
        = (Collection) allEnums.get(getClass());
      if (allValues == null)
      {
        allValues = new HashSet();
        allEnums.put(getClass(), allValues);
      }
      allValues.add(this);
    }

    protected static Collection/*<AbstractEnum>*/ getAllValues(Class clazz)
    {
      return Collections
        .unmodifiableCollection((Collection) allEnums.get(clazz));
    }
  }

  final class Thing extends AbstractEnum
  {
    final static Thing thing0 = new Thing();

    final static Thing thing1 = new Thing();

    private Thing()
    {}

    static Collection/*<Thing>*/ getAllValues()
    {
      return getAllValues(Thing.class);
    }
  }

Обратите внимание, что ему все еще нужны некоторые дополнительные важные функции, такие как безопасность потоков и сериализация (как описано в посте saua).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...