可以在Java 8中扩展枚举吗?
问题内容:
只是在玩,并想出了一个甜蜜的方法来使用此方法enum
在JavaEnum toString()方法中向s
添加功能。
一些进一步的修改使我 几乎 也可以添加整洁的(即不引发异常)反向查找,但是存在问题。报告:
error: valueOf(String) in X cannot implement valueOf(String) in HasValue
public enum X implements PoliteEnum, ReverseLookup {
overriding method is static
有办法吗?
这里的目的是(通过一个接口实现,使用default
像我politeName
在链接的答案中添加的方法一样)静默地添加一个在不引发异常的情况下lookup
执行该valueOf
功能的方法。可能吗?现在显然可以扩展enum
-
到目前为止,我的主要Java问题之一。
这是我失败的尝试:
public interface HasName {
public String name();
}
public interface PoliteEnum extends HasName {
default String politeName() {
return name().replace("_", " ");
}
}
public interface Lookup<P, Q> {
public Q lookup(P p);
}
public interface HasValue {
HasValue valueOf(String name);
}
public interface ReverseLookup extends HasValue, Lookup<String, HasValue> {
@Override
default HasValue lookup(String from) {
try {
return valueOf(from);
} catch (IllegalArgumentException e) {
return null;
}
}
}
public enum X implements PoliteEnum/* NOT ALLOWED :( , ReverseLookup*/ {
A_For_Ism, B_For_Mutton, C_Forth_Highlanders;
}
public void test() {
// Test the politeName
for (X x : X.values()) {
System.out.println(x.politeName());
}
// ToDo: Test lookup
}
问题答案:
您使设计过于复杂。如果您愿意接受default
只能在实例上调用方法,那么整个代码可能如下所示:
interface ReverseLookupSupport<E extends Enum<E>> {
Class<E> getDeclaringClass();
default E lookup(String name) {
try {
return Enum.valueOf(getDeclaringClass(), name);
} catch(IllegalArgumentException ex) { return null; }
}
}
enum Test implements ReverseLookupSupport<Test> {
FOO, BAR
}
您可以使用以下方法进行测试:
Test foo=Test.FOO;
Test bar=foo.lookup("BAR"), baz=foo.lookup("BAZ");
System.out.println(bar+" "+baz);
非抛出/捕获的替代方案是:
interface ReverseLookupSupport<E extends Enum<E>> {
Class<E> getDeclaringClass();
default Optional<E> lookup(String name) {
return Stream.of(getDeclaringClass().getEnumConstants())
.filter(e->e.name().equals(name)).findFirst();
}
使用像:
Test foo=Test.FOO;
Test bar=foo.lookup("BAR").orElse(null), baz=foo.lookup("BAZ").orElse(null);
System.out.println(bar+" "+baz);