gpt4 book ai didi

Java泛型根据值返回枚举

转载 作者:行者123 更新时间:2023-11-29 04:33:43 25 4
gpt4 key购买 nike

我有许多枚举在它们之间共享该方法。如果可能的话,我想把它移到一个接口(interface)上,这样我就不必复制它,而且代码看起来会更清晰。但是经过很多努力,我仍然无法将方法移动到接口(interface)。

public enum TypeA {
ValueAA ("Value AA"),
ValueAB ("Value AB");

private final String type;

TypeA (final String type) {
this.type = type;
}

@JsonValue
public String getType() {
return this.type;
}

@JsonCreator
public static TypeA fromValue(final String value) {
for (TypeA t : TypeA.values()) {
if (t.getType().equalsIgnoreCase(value)) {
return t;
}
}

StringBuilder allTypes = new StringBuilder();
boolean bFirstTime = true;
for (TypeA val : TypeA.values()) {
allTypes.append(bFirstTime ? "" : ", ").append(val);
bFirstTime = false;
}

throw new IllegalArgumentException(value + " is an invalid value. Supported values are " + allTypes);
}
}

public enum TypeB {
ValueBA ("Value BA"),
ValueBB ("Value BB");

private final String type;

TypeB (final String type) {
this.type = type;
}

@JsonValue
public String getType() {
return this.type;
}

@JsonCreator
public static TypeB fromValue(final String value) {
for (TypeB t : TypeB.values()) {
if (t.getType().equalsIgnoreCase(value)) {
return t;
}
}

StringBuilder allTypes = new StringBuilder();
boolean bFirstTime = true;
for (TypeB val : TypeB.values()) {
allTypes.append(bFirstTime ? "" : ", ").append(val);
bFirstTime = false;
}

throw new IllegalArgumentException(value + " is an invalid value. Supported values are " + allTypes);
}
}

使用泛型和 Java 8 是否可以将 getTypefromValue 方法移动到一个接口(interface),以便我可以在所有 Enum 之间共享?另请注意 Jackson 注释 JsonValueJsonCreator

最佳答案

您可以将 fromValue 实现移动到 interface,但是,我想,您必须在具体类型中保留 stub 以支持 JSON 工厂注释:

interface TypeX {
String getType();
static <T extends Enum<T>&TypeX> T fromValue(String value, Class<T> type) {
EnumSet<T> all=EnumSet.allOf(type);
for (T t: all) {
if (t.getType().equalsIgnoreCase(value)) {
return t;
}
}
throw new IllegalArgumentException(all.stream().map(t -> t.getType())
.collect(Collectors.joining(", ",
value+" is an invalid value. Supported values are ", "")));
}
}

public enum TypeA implements TypeX {
ValueAA ("Value AA"),
ValueAB ("Value AB");

private final String type;

TypeA (final String type) {
this.type = type;
}

@JsonValue
public String getType() {
return this.type;
}

@JsonCreator
public static TypeA fromValue(final String value) {
return TypeX.fromValue(value, TypeA.class);
}
}

enum TypeB implements TypeX {
ValueBA ("Value BA"),
ValueBB ("Value BB");

private final String type;

TypeB (final String type) {
this.type = type;
}

@JsonValue
public String getType() {
return this.type;
}

@JsonCreator
public static TypeB fromValue(final String value) {
return TypeX.fromValue(value, TypeB.class);
}
}

为了完整性,由于类型属性是不变的,如果我们使用不同的实现,则可以将 getType 方法移动到 interface:

interface TypeX {
@Retention(RetentionPolicy.RUNTIME) @interface Type { String value(); }

@JsonValue default String getType() {
for(Field f: getDeclaringClass().getDeclaredFields()) try {
if(f.isEnumConstant() && f.get(null)==this) {
return f.getAnnotation(Type.class).value();
}
} catch(IllegalAccessException ex) {
throw new AssertionError(ex);
}
throw new IllegalStateException();
}

Class<? extends TypeX> getDeclaringClass();

static <T extends Enum<T>&TypeX> T fromValue(String value, Class<T> type) {
EnumSet<T> all=EnumSet.allOf(type);
for (T t: all) {
if (t.getType().equalsIgnoreCase(value)) {
return t;
}
}
throw new IllegalArgumentException(all.stream().map(t -> t.getType())
.collect(Collectors.joining(", ",
value+" is an invalid value. Supported values are ", "")));
}
}

public enum TypeA implements TypeX {
@Type("Value AA") ValueAA,
@Type("Value AB") ValueAB;

@JsonCreator
public static TypeA fromValue(final String value) {
return TypeX.fromValue(value, TypeA.class);
}
}

enum TypeB implements TypeX {
@Type("Value BA") ValueBA,
@Type("Value BB") ValueBB;

@JsonCreator
public static TypeB fromValue(final String value) {
return TypeX.fromValue(value, TypeB.class);
}
}

但这有几个缺点,例如基于反射的访问在编译时不被检查,并且在运行时可能具有性能劣势。而且我不知道 @JsonValue 出现在从 interface 继承的 default 方法时是否会以预期的方式得到尊重。

关于Java泛型根据值返回枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42660806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com