Остановка повторения в перечислениях Java - PullRequest
3 голосов
/ 02 июля 2011

У меня есть следующий 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 и сохранить конструктор и свойство.

Ответы [ 4 ]

6 голосов
/ 03 июля 2011

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);
}
3 голосов
/ 02 июля 2011

Почему бы не взять перечисления из класса и создать автономный файл перечислений, в котором для всей обработки используется только второй (файл с 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 голосов
/ 02 июля 2011

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

0 голосов
/ 02 июля 2011

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