使用通配符类<! - ? - >从枚举类中检索枚举

时间:2015-02-27 00:15:03

标签: java generics enums java-8

我有以下代码

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

我在这里尝试甚至是可能的,还是有一些我不知道的仿制药魔法?

1 个答案:

答案 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.classA,同时实施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

无需额外的实用方法。