Java泛型枚举作为参数

Java泛型枚举作为参数,java,generics,enums,Java,Generics,Enums,因此,我定义了几个枚举,如下所示。我有一个使用枚举来查找值的方法 public enum MyEnum1 { STRING1("My String1"), STRING2("My String2"), STRING3("My String3"), STRINGLESS("String not found"); private String s; private MyEnum1(String s) { this.s = s; } public Str

因此,我定义了几个枚举,如下所示。我有一个使用枚举来查找值的方法

public enum MyEnum1
{
   STRING1("My String1"),
   STRING2("My String2"),
   STRING3("My String3"),
   STRINGLESS("String not found");

   private String s;

   private MyEnum1(String s) { this.s = s; }

   public String getValue() { return s; }
}

public enum MyEnum2
{
   STRING1("My String1"),
   STRING2("My String2"),
   STRING3("My String3"),
   STRINGLESS("String not found");

   private String s;

   private MyEnum2(String s) { this.s = s; }

   public String getValue() { return s; }
}

public class MyClass1
{
    public static String getPlacement(String myString)
    {
        for (MyEnum1 a: MyEnum1.values())
            if (myString.contains(a.toString()))
                return a.getValue();

        return MyEnum1.STRINGLESS.getValue();
     }
}

public class MyClass2
{
    public static String getPlacement(String myString)
    {
        for (MyEnum2 a: MyEnum2.values())
            if (myString.contains(a.toString()))
                return a.getValue();

        return MyEnum2.STRINGLESS.getValue();
     }
}
现在我已经定义了5个枚举,它们都由相同的getPlacement方法处理,但是我必须用MyEnum2、MyEnum3创建5个不同的MyClass类(MyClass2、MyClass3…)。。。在For循环中进行硬编码以使其发生

我试过

public static String getPlacement(Enum e, String myString) {}

publicstaticstringgetplacement(enume,stringmystring){
但两者都不起作用


我想将一个枚举作为参数传递给getPlacement方法,这样就只允许有一个MyClass类可以处理5个不同的枚举。这可能吗?

将这样的接口添加到代码中

public interface Named {
    String name();
}
让您的所有枚举像这样实现它

public enum MyEnum1 implements Named {...}
然后使用如下接口声明您的方法:

public static String getPlacement(Named enumValue, String myString) {}
getPlacement()
方法调用
enumValue.name()
的内部,而不是
toString()
,尽管您可以对toString()执行完全相同的操作,但这取决于您将在接口定义中使用什么(可以随意命名,不一定是
命名的

顺便说一下,使用单个字母作为变量名通常被认为是一种不好的做法。

枚举基类有一个静态工厂方法
valueOf(class,String)
,用于构造任意枚举实例。通过一些泛型魔法,你应该能够解决你的问题

public enum MyEnum1 {
   STRING1("MyEnum1 String1"),
   STRING2("MyEnum1 String2"),
   STRING3("MyEnum1 String3"),
   STRINGLESS("MyEnum1 String not found");

   private String s;
   private MyEnum1(String s) { this.s = s; }

   @Override
   public String toString() { return s; }
}

public enum MyEnum2 {
   STRING1("MyEnum2 String1"),
   STRING2("MyEnum2 String2"),
   STRING3("MyEnum2 String3"),
   STRINGLESS("MyEnum2 String not found");

   private String s;
   private MyEnum2(String s) { this.s = s; }

   @Override
   public String toString() { return s; }
}

public static void main(String[] args) {
    System.out.println(getPlacement(MyEnum1.class, "STRING1").name());
    System.out.println(getPlacement(MyEnum2.class, "STRING3").name());
    System.out.println(getPlacement(MyEnum2.class, "foobar").name());
}

public static <T extends Enum<T>> Enum<T> getPlacement(Class<T> clazz, String value) {
    try {
        return Enum.valueOf(clazz, value);
    } catch (IllegalArgumentException e) {
        return Enum.valueOf(clazz, "STRINGLESS");
    }
 }
公共枚举MyEnum1{
STRING1(“MyEnum1 STRING1”),
STRING2(“MyEnum1 STRING2”),
第3条(“MyEnum1第3条”),
无字符串(“未找到MyEnum1字符串”);
私有字符串;
私有MyEnum1(字符串s){this.s=s;}
@凌驾
公共字符串toString(){return s;}
}
公共枚举MyEnum2{
STRING1(“MyEnum2 STRING1”),
STRING2(“MyEnum2 STRING2”),
第3条(“MyEnum2第3条”),
无字符串(“未找到MyEnum2字符串”);
私有字符串;
私有MyEnum2(字符串s){this.s=s;}
@凌驾
公共字符串toString(){return s;}
}
公共静态void main(字符串[]args){
System.out.println(getPlacement(MyEnum1.class,“STRING1”).name());
System.out.println(getPlacement(MyEnum2.class,“STRING3”).name());
System.out.println(getPlacement(MyEnum2.class,“foobar”).name();
}
公共静态枚举getPlacement(类clazz,字符串值){
试一试{
返回枚举值of(clazz,value);
}捕获(IllegalArgumentException e){
返回枚举值(clazz,“STRINGLESS”);
}
}

要保留
getPlacement
的确切语义,您可以这样做:

interface StringValue {
    String getValue();
}

enum MyEnum1 implements StringValue {
    ...
    private String stringValue;
    ...

    @Override
    public String getValue() {
        return stringValue;
    }
}

static <E extends Enum<E> & StringValue>
String getPlacement(Class<E> enumClass, String inValue) {
    for(E constant : enumClass.getEnumConstants()) {
        if(inValue.contains(constant.toString()))
            return constant.getValue();
    }
    return Enum.valueOf(enumClass, "STRINGLESS").getValue();
}
接口字符串值{
字符串getValue();
}
枚举MyEnum1实现StringValue{
...
私有字符串字符串值;
...
@凌驾
公共字符串getValue(){
返回字符串值;
}
}
静止的
字符串getPlacement(类enumClass,字符串无效){
对于(E常量:enumClass.getEnumConstants()){
if(inValue.contains(constant.toString()))
返回常量.getValue();
}
返回Enum.valueOf(enumClass,“STRINGLESS”).getValue();
}
我不确定这里的确切语义对你是否真的很重要。如果不是,还有更简单的方法。如果您不需要
包含
,可以直接使用。如果您可以重写
toString
(因为您也可以使用),那么就不需要接口


而且,就像所有使用enum的复杂情况一样,如果不使用enum,事情可能会简单得多。带有私有构造函数和公共静态final
常量的
final
类可以做很多enum不能做的事情(比如从抽象超类型继承…。

看起来您的
getPlacement
应该返回
T
。因为enum的定义是递归的,所以enum应该得到相同的输出。我发现添加的内容更具可读性;但是你说得对,详细性是不必要的。感谢你花时间提供帮助,但是getPlacement返回的字符串值与我传递给它的字符串值相同,而不是MyEnum#string#这是一个例外,我无法使用valueOf()循环枚举值。就好像它没有继承枚举的迭代能力一样。哦,我只使用单字母变量作为迭代器和计数器。我只是变得懒惰,没有创建MyVar1或其他什么,我只是使用了s:-谢谢你的帮助这不是我想要的!我正在寻找键、值对,我需要控制键的检查顺序,这就是我选择Enum的原因。我将用户放在LDAP树中,您可以是董事会成员、教员、员工、顾问、校友……和/或学生的任意组合。我需要按照我刚才列出的顺序,通过用户类型的层次结构来确定您的容器(它控制您的权限)。如果你是董事会成员和学生,你应该被放置在董事会容器中。教员和职员=职员等等。再次感谢!!!应该说它完全符合我的要求!非常感谢!!
interface StringValue {
    String getValue();
}

enum MyEnum1 implements StringValue {
    ...
    private String stringValue;
    ...

    @Override
    public String getValue() {
        return stringValue;
    }
}

static <E extends Enum<E> & StringValue>
String getPlacement(Class<E> enumClass, String inValue) {
    for(E constant : enumClass.getEnumConstants()) {
        if(inValue.contains(constant.toString()))
            return constant.getValue();
    }
    return Enum.valueOf(enumClass, "STRINGLESS").getValue();
}