停止Java枚举中的重复

时间:2011-07-02 19:33:38

标签: java enums

我在Java类中有以下enum

public enum Resolution {
    RES_32 (32),
    RES_64 (64);
    private final int asInt;
    private Resolution(int asInt) {
        this.asInt = asInt;
    }
};

我有更多类需要类似enum的类,具有相同的asInt属性和相同的构造函数,但具有不同的常量。所以,在另一个课程中,我需要以下enum

public enum Resolution {
    RES_32 (32),
    RES_64 (64),
    RES_128 (128);
    private final int asInt;
    private Resolution(int asInt) {
        this.asInt = asInt;
    }
};

如果这是一个类,我可以使用继承来不重复构造函数中的代码(并且可能会为该asInt属性创建一个getter)。每次我需要Resolution enum时,我该怎么做才能停止重复自己?理想情况下,我只想为每个Resolution指定常量,并保留构造函数和属性。

4 个答案:

答案 0 :(得分:6)

在这种情况下,

EnumSet可能会有所帮助。鉴于以下内容,

public enum Resolution {

    RES_32(32),
    RES_64(64),
    RES_128(128),
    RES_256(256);

    public static Set<Resolution> deluxe = EnumSet.allOf(Resolution.class);
    public static Set<Resolution> typical = EnumSet.range(RES_64, RES_128);
    public static Set<Resolution> ecomomy = EnumSet.of(RES_32);

    private final int asInt;

    private Resolution(int asInt) {
        this.asInt = asInt;
    }
};

可以使用适当命名的集合,如下所示。

for (Resolution r : Resolution.deluxe) {
    System.out.println(r.asInt);
}

答案 1 :(得分:3)

为什么不将枚举从类中取出并创建一个仅使用第二个(RES_128)的独立枚举文件进行所有处理?

编辑1
你的评论:

  

因为并非所有类都应具有相同的常量。有些需要只有32和64,而其他需要有32,64和128

确实只有一个分辨率“类型”,这表明应该只有一个分辨率枚举,但问题似乎是并非所有类都接受所有分辨率。一种可能的解决方案是使用一个枚举来表示所有分辨率,但将EnumMap用于不同的类,其中一些类标记分辨率为false或意味着对该类无效。

编辑2
或者甚至只有一个接受枚举的HashSet。

编辑3
例如,使用HashSet

class Foo002 {
   public static Set<Resolution> allowedResolution = new HashSet<Resolution>();
   static {
      allowedResolution.add(Resolution.RES_32);
      allowedResolution.add(Resolution.RES_64);
   }
   private Resolution resolution;

   public void setResolution(Resolution resolution) {
      if (!(allowedResolution.contains(resolution))) {
         throw new IllegalArgumentException("Disallowed Resolution: " + resolution);
      }
      this.resolution = resolution;
   }
}

enum Resolution {
   RES_32 (32),
   RES_64 (64),
   RES_128 (128);
   private final int asInt;
   private Resolution(int asInt) {
       this.asInt = asInt;
   }

   public int getIntValue() {
      return asInt;
   }
};

答案 2 :(得分:2)

我会将新值添加到原始枚举中,并让新类重新使用它。为什么他们不能打电话给你发布的第一个?如果你复制并扩展第一个构造函数,那么你遇到的问题不仅仅是重复构造函数。

答案 3 :(得分:0)

以下内容允许您在运行时使用枚举,这是参考链接http://www.theserverside.com/news/thread.tss?thread_id=50190

Constructor con = Day.class.getDeclaredConstructors()[0]; 
Method[] methods = con.getClass().getDeclaredMethods(); 
for (Method m : methods) 
{ 
    if (m.getName().equals("acquireConstructorAccessor")) 
    { 
        m.setAccessible(true); 
        m.invoke(con, new Object[0]); 
    } 
}

Field[] fields = con.getClass().getDeclaredFields(); 
Object ca = null; 
for (Field f : fields) 
{ 
    if (f.getName().equals("constructorAccessor")) 
    { 
        f.setAccessible(true); 
        ca = f.get(con); 
    } 
}

Method m = ca.getClass().getMethod( "newInstance", new Class[] { Object[].class }); 
m.setAccessible(true); 
Day v = (Day) m.invoke(ca, new Object[] { new Object[] { "VACATION", Integer.MAX_VALUE } }); 
System.out.println(v.getClass() + ":" + v.name() + ":" + v.ordinal());