加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-14 17:44:13 所属栏目:Java 来源:网络整理
导读:刚刚玩,并提出了一个甜蜜的方式来添加功能到 Java Enum toString() method与 this的枚举. 一些进一步的修补使我几乎可以增加一个整洁(即不抛出异常)反向查找,但有一个问题.报告: error: valueOf(String) in X cannot implement valueOf(String) in HasValue
刚刚玩,并提出了一个甜蜜的方式来添加功能到 Java Enum toString() method与 this的枚举.

一些进一步的修补使我几乎可以增加一个整洁(即不抛出异常)反向查找,但有一个问题.报告:

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

有办法吗

这里的目标是默认添加(通过一个默认方法,如我在链接的答案中添加了politeName)的一个接口实现一个没有抛出异常的valueOf函数的查找方法.可能吗?显然现在可以将枚举扩展为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
}

解决方法

你的设计过于复杂.如果您愿意接受只能在实例上调用默认方法,则整个代码可能如下所示:
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);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读