Я искал несколько дней, чтобы найти ответ на этот вопрос, основанный на производительности.
Покопавшись в Интернете, я узнал, что есть несколько способов использования Enums в java, хорошо документированных в здесь .
Что ж, определенно для начала хотелось бы использовать Enums в операторе switch-case , который обеспечивает ясность и лучшее понимание кода. Но с другой стороны, у нас есть реализация типа Enums в стиле Visitor * , которая обеспечивает безопасность типов и расширяемость. Обсуждается здесь .
Сказав это и вернувшись к первоначальной идее, стоящей за этим вопросом, я до сих пор узнал, что если конструкция переключающего регистра правильно спроектирована с использованием Enums, что гарантирует, что значения регистра не редки, и что объявление Enum в том же модуле компиляции, что и оператор switch-case, java-компилятор выполняет некоторую оптимизацию по произведенному байт-коду путем реализации такой конструкции, как таблица переходов (обсуждается в здесь и в других местах а также на сайте Sun, на который я потерял ссылку). Теперь это определенно повышает производительность по сравнению с множественной / вложенной конструкцией if-else.
Мой вопрос заключается в том, как java реализует реализацию Enums на основе шаблонов посетителей в результирующем байт-коде и каково повышение производительности по сравнению с реализацией на основе switch-case , если есть?
И какой тип реализации я бы предпочел, учитывая, что мои Enums могут вырасти в будущем, и я также заинтересован в производительности. В настоящее время в моем Enum есть около 19 с лишним констант.
EDIT
У меня есть класс, который хранит некоторую информацию о переменных игры. Одной из переменных является тип Enum .
public class GameObject {
private Shape mShape;
public Shape getShape() {
return mShape;
}
.
.
.
public static enum Shape {
SHAPE1, SHAPE2, SHAPE3, SHAPE4, ..., SHAPE20
};
public void drawShape() {
switch (this.mShape) {
case SHAPE1:
drawShape1();
break;
case SHAPE2:
drawShape2();
break;
case SHAPE3:
drawShape3();
break;
case SHAPE4:
drawShape4();
break;
.
.
.
.
.
case SHAPE20:
drawShape20();
break;
default:
drawUnknown();
break;
}
}
}
Позже я понял, что нужно отделить информацию от логики, и поэтому создал другой класс и переместил Enum Shape из GameObject в этот новый класс GraphicModel , и вместо того, чтобы switch-case там, я реализовал методы, специфичные для констант . И да, я поместил правильные операторы импорта в любой класс после этой модификации.
public class GraphicModel {
public void drawGraphicFromObject(GameObject gameObject) {
gameObject.getShape().draw();
}
public static enum Shape {
// This method is not public, instead is only called by GraphicModel
abstract void draw();
SHAPE1 {
@Override
void draw() {
// some transformations
}
},
SHAPE2 {
@Override
void draw() {
// Some different transformation
}
},
SHAPE3 {
@Override
void draw() {
// Yet another transform
}
},
.
.
.
.
UNKNOWN {
@Override
void draw() {
//
}
};
}
}
Позже я даже реализовал это на основе шаблона посетителя , как предлагалось здесь
Итак, что мне нужно знать, так это то, какой способ реализации более эффективен? Определенно, для преобразования switch-case в таблицы переходов при компиляции java требует как декларации enum , так и операторов switch в одном и том же блок компиляции .
Должен ли я использовать switch основанную реализацию или постоянного метода реализацию в моем GraphicModel классе?
Скорее, чтобы было ясно, в чем разница в производительности?