【发布时间】:2020-05-24 06:45:18
【问题描述】:
我有一些枚举是 name("String") 和 value("Integer") 对,当前在每个枚举中我必须为 Json Deserialize 实现一个 @JsonCreator 方法,输入可以是名称或值
//User Enum
public enum UserType {
StakeHolder(1),...
private static final Map<String, UserType> helper = ImmutableMap.<String, UserType>builder()
.put(String.valueOf(StakeHolder.getValue()), StakeHolder)
.put(StakeHolder.name(), StakeHolder)
.build();
@JsonCreator
public static UserType jsonDeserialize(String json) {
return helper.get(json);
}
}
//Role Enum
public enum RoleType {
Admin(1),...
private static final Map<String, RoleType> helper = ImmutableMap.<String, RoleType>builder()
.put(String.valueOf(Admin.getValue()), Admin)
.put(Admin.name(), Admin)
.build();
@JsonCreator
public static RoleType jsonDeserialize(String json) {
return helper.get(json);
}
}
但我想知道是否有任何方法可以创建一个可以实现整体枚举的抽象类,这是为了避免在我的每个枚举中始终实现类似的“重复”代码。当前的代码就像
public abstract class JsonDeserializeEnum<E extends Enum<E>> {
// protected Enum<E> myEnums;
// private static final Map<String, E> myEnumHelper; ???
public JsonDeserializeEnum() {
super();
// how to loop through myEnums to do something like
// for(E iterator : myEnums.value()) not work...myEnums is not a collection of enums?
// myEnumHelper.put(String.valueOf(iterator.getValue()), (E) iterator);
// myEnumHelper.put(iterator.name, (E) iterator);
}
@JsonCreator
public static E jsonDeserialize(String json) {
return myEnumHelper.get(json);
}
}
//then
public enum UserType implements JsonDeserializeEnum<UserType>{
StakeHolder(1),...
}
public enum RoleType implements JsonDeserializeEnum<RoleType>{
Admin(1),...
}
我在这里遇到了两个挑战,
1) 我想在我的抽象类中有一个初始化/构造函数,可以将所有可用的枚举加载到静态映射中(仅一次),例如,
调用UserType时,将所有用户类型枚举加载到静态映射中,然后从该映射中反序列化;调用RoleType时,将所有角色类型枚举加载到map中,然后从同一个map中反序列化
2)如果 No.1 是不可能的,那没关系,假设我是否会在我的抽象类中摆脱映射,但仍然使用我的每个枚举中定义的映射,我的抽象类是否知道并且可以使用我的枚举中定义的地图吗?
【问题讨论】:
-
除了你提议的实现中的关键冲突之外,主要问题是
jsonDeserialize()必须是static。这意味着您必须在每个枚举上声明它。您可以选择将查找逻辑外部化(例如通过将您的地图更改为在您的界面中使用枚举类型条目的地图地图),但这只会改善很少。 -
明白了!假设我要摆脱抽象类中的映射,但仍然使用每个 Enum 中定义的映射,我的抽象类是否知道并且可以使用 Enum 中定义的映射?
-
首先,你不能让你的枚举extend成为一个抽象类。你可以让它们实现一个接口。是的,你可以定义一个契约,让你的枚举实现一个返回本地地图的方法,但它必须是一个实例方法。当您回顾这样的实现时,您可能会发现您当前的版本比两个丑陋的设计更可取(我的观点)。
标签: java enums abstract-class generic-programming