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

4 ответа

Решение

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

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

Редактировать 1
Ваш комментарий:

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

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

Редактировать 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;
   }
};

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

Следующее позволяет вам работать с перечислениями во время выполнения, это ссылка 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());
Другие вопросы по тегам