EnumSet for 1.5之前的假枚举?

时间:2009-04-13 20:11:56

标签: java reflection

最近我一直在做很多这些

enum Thing {

    /* etc etc */

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

}

我想在1.5之前的Java中有类似的东西,即我想要类似的东西:

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 个答案:

答案 0 :(得分:4)

那是怎么回事:

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();
}

答案 1 :(得分:3)

在1.5之前的Java中没有直接的等价物。

在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.
}

您仍然需要记住向该方法添加任何新成员,但它更容易阅读(对大多数人来说)。

答案 2 :(得分:1)

关于如何在Jav 5之前的环境中定义类型安全枚举,有一个非常明确的模式。

它基本上是一个类,其值为public final static字段,私有构造函数(或更多)。

唯一的“难点”是获取序列化等详细信息(基本上是通过实现readResolve())。

This Javaworld Tip在这个问题上非常深入,this one还有更多关于这个问题的说法。

答案 3 :(得分:0)

在下面的解决方案中,每个枚举类都扩展了一个抽象基类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的帖子所述)。