java - 是否可以在 Java 8 中扩展枚举?

标签 java enums extend java-8

只是玩了一下,想出了一个很好的方法来为 Java Enum toString() method 中的 enum 添加功能。与 this .

一些进一步的修补让我几乎也添加了一个整洁的(即不抛出异常)反向查找,但是有一个问题。它正在报告:

error: valueOf(String) in X cannot implement valueOf(String) in HasValue
public enum X implements PoliteEnum, ReverseLookup {
overriding method is static

有办法吗?

此处的目的是静默添加(通过具有 default 方法的接口(interface)实现,就像我在链接的答案中添加 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);

关于java - 是否可以在 Java 8 中扩展枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22083689/

相关文章:

c# - 如何在实际类中引用枚举而不是 C# 中的基类

c# - 为什么枚举中不允许​​字段引用(或者这是编译器错误?)

javascript - BackboneJS 中意外的构造函数/扩展行为

python - 你能像字符串替换一样快捷地使用Python方法吗?

java - setTitle() 和 Thread.sleep()

java - 正则表达式 (java) 在单词之后只有空格或行尾

Java 输入流被阻塞

java - 如果可以的话,我可以在不使用java中的包装类的情况下对两个字符串值求和吗?

c++ - 已经在 Main.obj c++ 中定义

Java - 扩展接口(interface)