gpt4 book ai didi

java - 使用通配符 Class 从枚举类中检索枚举

转载 作者:行者123 更新时间:2023-11-29 05:10:32 25 4
gpt4 key购买 nike

我有以下代码

public interface SomeInterface {    }


public class TestConstants {
public static <E extends Enum<E> & SomeInterface> E getEnumString(Class<E> clazz, String s){
for(E en : EnumSet.allOf(clazz)){
if(en.name().equalsIgnoreCase(s)){
return en;
}
}
return null;
}
public enum A implements SomeInterface {
V1,
V2,
V3;
}

public enum B implements SomeInterface {
V1,
V2,
V3;
}
// And so on.......
}

我可以在代码的其他地方调用 call

TestConstants.getEnumString(TestConstants.B.Class,"V2")

它会返回TestConstants.B.V2一切都很好。

但我的问题是,如果我不知道要搜索的实际 Enum 类怎么办即

Class<?> enumClass包含其中一个枚举,但我不知道是哪个。现在我从 TestConstants 类外部的代码中,我可以使用类似下面的内容

if (enumClass.equals(TestConstants.A.class)) {
TestConstants.getEnumString(TestConstants.A.class,value);
} else if (enumClass.equals(TestConstants.B.class)) {
TestConstants.getEnumString(TestConstants.B.class,value);
} else if (enumClass.equals(TestConstants.C.class)) {
// And so on....

但我真的很想将这段代码移到 TestConstants 类中。但我似乎做不到。例如,如果我添加此功能

public static <E extends Enum<E> & SomeInterface> E fromUnknownClass(Class<?> enumClass, String name) {
if (enumClass.equals(TestConstants.A.class)) {
return TestConstants.fromString(TestConstants.A.class,name); <-- Compile error
} else if .......
.......
}

我得到以下编译错误

incompatible types: inference variable E has incompatible bounds equality constraints: 
TestConstants.A upper bounds: E,java.lang.Enum<E>,SomeInterface

我在这里尝试的是可能的,还是有一些我不知道的泛型魔法?

最佳答案

你正在让你的生活变得不必要的艰难。在你的通用签名中

public static <E extends Enum<E> & SomeInterface> E getEnumString(Class<E> clazz, String s)

SomeInterface的声明已经过时了。毕竟,无论特定的 enum 是否有效,该方法都有效。工具 SomeInterface .它保证返回的类型与您传入的类匹配(阅读:类型为 E )因此结果将实现 SomeInterface 如果 E工具 SomeInterface .

所以如果你把方法改成

public static <E extends Enum<E>> E getEnumString(Class<E> clazz, String s)

并传入A.classB.class结果将是 A 类型或 B , 分别执行 SomeInterface .这甚至适用于调用者可能确实需要约束 SomeInterface 的通用上下文。已实现:

public <T extends Enum<T>&SomeInterface> void doSomethingWithSomeInterface(Class<T> cl) {
// works without getEnumString declaring SomeInterface ...
T t=getEnumString(cl, "V1");
}

但是,如果您传入 Class<?> , 没有人能说结果是否会执行 SomeInterface验证它的最佳方法是进行普通转换或 instanceof关于结果。

如果您按上述方式更改了签名,即使是未知类型,它也很容易使用:

Class<?> cl=A.class; // the "unknown" type Class<?>
Object obj=getEnumString(cl.asSubclass(Enum.class), "V1");

请注意,如果您不需要不区分大小写的匹配,有更简单的方法来获得 enum持续的。对于已知类型,您可以简单地调用,例如A.valueOf("V1") ,对于泛型方法,它很简单:

public static <E extends Enum<E>> E getEnumString(Class<E> clazz, String s){
return Enum.valueOf(clazz, s);
}

这使得整个实用程序方法过时为 Enum.valueOf(Class, String)已经是那个实用方法了。

即使您需要不区分大小写的查找,您也可以考虑 enum常量通常全部大写,如果您遵守此约定,整个操作将变为:

Class<?> clazz=A.class; // simulate unknow type
String name="v1"; // for case insensitive match
// the operation:
Object aV1=Enum.valueOf(clazz.asSubclass(Enum.class), name.toUpperCase(Locale.ROOT));
SomeInterface si=(SomeInterface)aV1;

无需额外的实用方法。

关于java - 使用通配符 Class<?> 从枚举类中检索枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28755310/

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