我觉得我只是缺少了一些东西,或者这可能不是使用枚举。我几乎知道我可以使用枚举清除此代码:
int bookTypeId = 1; //dynamic
String bookTypeName;
switch (bookTypeId) {
case 1:
bookTypeName = "Fantasy";
break;
case 2:
bookTypeName = "Horror";
break;
case 3:
bookTypeName = "Action";
break;
default:
bookTypeName = "Error";
}
因此,我将其存储在另一个类中,如下所示:
public static enum BookType {
HORROR("Horror"), FANTASY("Fantasy"), ACTION("Action"), ERROR("Error");
private String name;
BookType(String name) {
this.name = name;
}
public String getType() {
return name;
}
}
现在像这样使用它:
switch (bookTypeId) {
case 1:
bookTypeName = MYConstants.BookType.FANTASY.getType();
break;
case 2:
bookTypeName = MYConstants.BookType.HORROR.getType();
break;
case 3:
bookTypeName = MYConstants.BookType.ACTION.getType();
break;
default:
bookTypeName = MYConstants.BookType.ERROR.getType();
}
我想更进一步,并清理此switch语句的主类(这就是为什么我开始查看枚举的原因,因为现在它似乎在做同样的事情)。
是否可以在枚举内移动此开关/盒?然后以如下方式使用枚举
bookTypeName = MYConstants.BookType.getType(bookTypeId);
也有可能使用final声明此枚举(当我尝试时它正在抱怨),或者它已经是final?
谢谢!
最佳答案
像下面这样?
public static enum BookType {
HORROR(1, "Horror"),
FANTASY(2, "Fantasy"),
ACTION(3, "Action");
private static final Map<Integer, BookType> LOOKUP;
static {
LOOKUP = new HashMap<>();
for (final BookType type : values()) {
LOOKUP.put(type.id, type);
}
}
public static BookType getById(final int id) {
final BookType bt = LOOKUP.get(id);
if (bt == null) {
throw new IllegalArgumentException("Invalid book id " + id);
}
return bt;
}
private final int id;
private final String name;
BookType(final int id, final String name) {
this.id = id;
this.name = name;
}
public String getType() {
return name;
}
}
用法:
final BookType type = BookType.getById(bookTypeId);
您可以删除
String
属性并覆盖toString()
:@Override
public String toString() {
final String name = name();
return name.substring(0, 1) + name.substring(1).toLowerCase();
}
要回答您的最后一个问题,
enum
不能为final
。 enum
是语法糖;编译器将通过首先创建class BookType extends Enum<BookType
并使用指定名称创建新static final
的class
实例来对其进行解糖。实际的enum
声明本身并不是真正的class
声明,因此不能为final
。此外,如果您的enum
常量本身覆盖或实现方法(如this example中的方法),则每个enum
常量将是扩展Booktype
的匿名类-如果enum
是final
并且已转置到BookType
类,则将不允许这种行为;而且原因并不完全清楚。