我有以下代码
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.......
}
在代码的其他地方,我可以拨打电话
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
我在这里尝试甚至是可能的,还是有一些我不知道的仿制药魔法?
答案 0 :(得分:3)
你正在不必要地努力工作。在您的通用签名
中public static <E extends Enum<E> & SomeInterface> E getEnumString(Class<E> clazz, String s)
SomeInterface
的声明已过时。毕竟,无论特定enum
是否实现SomeInterface
,该方法都有效。它保证返回的类型与您传入的类匹配(读取:类型为E
)因此,如果 SomeInterface
实现{{}},则结果将实现E
{1}}。
因此,如果您将方法更改为
SomeInterface
并传入public static <E extends Enum<E>> E getEnumString(Class<E> clazz, String s)
或A.class
,结果将分别为B.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
无需额外的实用方法。