所以我有几个Enums定义如下。我有一个方法,使用Enum来查找值。
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个Enums,它们都被同一个getPlacement方法处理,但是我必须用MyEnum2创建5个不同的MyClass类(MyClass2,MyClass3 ...),MyEnum3 ...在For循环中硬编码让它成真。
我试过......
public static String getPlacement(Enum e, String myString) {}
和
public static String getPlacement(Enum<?> e, String myString) {}
但不起作用。
我想将一个Enum作为参数传递给getPlacement方法,因此我只能拥有一个可以处理5个不同枚举的MyClass类。这可能吗?
答案 0 :(得分:1)
将此类界面添加到您的代码中。
public interface Named {
String name();
}
让你的所有枚举都像
一样实现它public enum MyEnum1 implements Named {...}
然后使用如下界面声明您的方法:
public static String getPlacement(Named enumValue, String myString) {}
在getPlacement()
方法调用enumValue.name()
而不是toString()
内部,虽然你可以使用toString()完全相同,但取决于你在接口定义中使用的内容(可以按你的意愿命名,不一定是Named
)。
顺便说一句,使用单个字母作为变量名通常被认为是一种不好的做法。
答案 1 :(得分:1)
要保留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();
}
我不确定这里的确切语义对你来说是否真的很重要。如果他们不是,那就有更简单的方法。如果您不需要contains
,则可以使用Enum#valueOf
。如果您可以覆盖toString
(因为您也可以使用Enum#name
),那么您不需要界面。
而且,就像所有复杂的枚举情况一样,如果你不使用枚举,事情可能会简单得多。具有私有构造函数和final
常量的public static final
类可以执行枚举不能执行的许多操作(例如从抽象超类型继承...)。
答案 2 :(得分:0)
Enum基类java.lang.Enum具有静态工厂方法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");
}
}