Generic class field in enum
本问题已经有最佳答案,请猛点这里访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public enum Dictionaries { FIRST_DICTIONARY(FirstDictionary.class), SECOND_DICTIONARY(SecondDictionary.class); private Class<? extends DictionaryModel> clazz; private Dictionary(Class<? extends DictionaryModel> clazz) { this.clazz = clazz; } public Class<? extends DictionaryModel> clazz() { return this.clazz; } } |
我有这个枚举。
现在我很想这样做:
这个设计显然是不可能的,我想不出实现它的方法。有什么办法吗?我可以访问整个代码,所以我可以修改所有内容,包括接口(甚至删除它)。
我简化了所有这些,重点是每个字典都是一个数据库表,我有一个共同的DAO(而不是每个字典的DAO),现在我必须对我想要避免的每次读取的结果进行强制转换。我知道普通的刀不是一个好主意(或者根本不是刀)。
在DAO本身或
我很欣赏任何想法,甚至完全改变了设计。
正如jorn vernee所解释的,
最简洁的解决方案,允许您编写
1 | Class<FirstDictionary> clazz = Dictionaries.FIRST_DICTIONARY.clazz(); |
将是
1 2 3 4 5 6 | public interface Dictionaries<T extends DictionaryModel> { Dictionaries<FirstDictionary> FIRST_DICTIONARY = () -> FirstDictionary.class; Dictionaries<SecondDictionary> SECOND_DICTIONARY = () -> SecondDictionary.class; Class<T> clazz(); } |
但是,你可以再确认
当前无法使用枚举。您给出的示例也在jep 301中给出:
1 2 3 4 5 6 7 8 9 10 11 12 | enum Argument<X> { // declares generic enum STRING<String>(String.class), INTEGER<Integer>(Integer.class), ... ; Class<X> clazz; Argument(Class<X> clazz) { this.clazz = clazz; } Class<X> getClazz() { return clazz; } } Class<String> cs = Argument.STRING.getClazz(); //uses sharper typing of enum constant |
但这不是语言的一部分
在此之前,您必须重构代码才能使用类,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | interface DictionaryModel {} class FirstDictionary implements DictionaryModel {} class SecondDictionary implements DictionaryModel {} // Following a model similar to how enums are implemented, but with sharper typing: abstract class Dictionaries<T extends DictionaryModel> { public static final Dictionaries<FirstDictionary> FIRST_DICTIONARY = new Dictionaries<>(FirstDictionary.class) {}; public static final Dictionaries<SecondDictionary> SECOND_DICTIONARY = new Dictionaries<>(SecondDictionary.class) {}; private final Class<T> clazz; private Dictionaries(Class<T> clazz) { this.clazz = clazz; } public Class<T> clazz() { return this.clazz; } } |
现在你可以这样做了:
1 | Class<FirstDictionary> clazz = Dictionaries.FIRST_DICTIONARY.clazz(); |