Остановка повторения в перечислениях Java

У меня есть следующий enum в классе Java:

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). Что я могу сделать, чтобы перестать повторяться каждый раз, когда мне нужен такой Resolution enum? В идеале я хотел бы просто указать константы для каждого Resolution и сохранить конструктор и свойство.

Ответ 1

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

Ответ 2

Почему бы не взять перечисления из класса и создать автономный файл перечисления, который использует только вторую (с RES_128) для всей обработки?

Изменить 1
Ваш комментарий:

Потому что не все классы должны иметь одинаковые константы. Некоторые должны иметь только 32 и 64, в то время как другие должны иметь 32, 64 и 128

На самом деле существует только один тип разрешения "Resolution", и это говорит о том, что должно быть только одно перечисление разрешения, но проблема заключается в том, что не все классы принимают все разрешения. Одним из возможных решений является использование одного перечисления для представления всех разрешений, но 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;
   }
};

Ответ 3

Я бы добавил новое значение в исходное перечисление и попросил новые классы повторно использовать его. Почему они не могут назвать первый, который вы опубликовали? У вас больше проблем, чем просто повторение конструктора, если вы копируете и расширяете первый.

Ответ 4

Ниже вы можете работать с перечислениями во время выполнения, это ссылка ссылки 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());