我觉得我只是缺少了一些东西,或者这可能不是使用枚举。我几乎知道我可以使用枚举清除此代码:

    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不能为finalenum是语法糖;编译器将通过首先创建class BookType extends Enum<BookType并使用指定名称创建新static finalclass实例来对其进行解糖。实际的enum声明本身并不是真正的class声明,因此不能为final。此外,如果您的enum常量本身覆盖或实现方法(如this example中的方法),则每个enum常量将是扩展Booktype的匿名类-如果enumfinal并且已转置到BookType类,则将不允许这种行为;而且原因并不完全清楚。

10-04 11:36
查看更多