枚举:每个实例独有的方法

Mr.*_*art 20 java compiler-construction syntax enums

另一个问题我了解到,在Java中可以为Enum的每个实例定义特定的方法:

public class AClass {

    private enum MyEnum{
        A { public String method1(){ return null; } },
        B { public Object method2(String s){ return null; } },
        C { public void method3(){ return null; } } ;
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

我很惊讶这甚至是可能的,这个"独有方法"特定于每个实例都有一个名称来查找文档吗?

此外,它是如何应该使用?因为下一个没有编译:

    private void myMethod () {
        MyEnum.A.method1();
    }
Run Code Online (Sandbox Code Playgroud)

我该如何使用这些"独家"方法?

San*_*rma 18

您需要在枚举中声明抽象方法,然后在特定的枚举实例中实现.

class Outer {

    private enum MyEnum {
        X {
            public void calc(Outer o) {
                // do something
            }
        },
        Y {
            public void calc(Outer o) {
                // do something different
                // this code not necessarily the same as X above
            }
        },
        Z {
            public void calc(Outer o) {
                // do something again different
                // this code not necessarily the same as X or Y above
            }
        };

        // abstract method
        abstract void calc(Outer o);
    }

    public void doCalc() {
        for (MyEnum item : MyEnum.values()) {
            item.calc(this);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*aný 14

您无法引用这些方法,因为您实际上是为每个枚举创建匿名(*)类.由于它是匿名的,因此您只能从匿名类本身或通过反射引用此类方法.

当您在枚举中声明抽象方法时,此技术非常有用,并且可以单独为每个枚举实现该方法.

(*)JLS 8.9枚举部分说:"枚举常量的可选类体隐式定义了一个匿名类声明(第15.9.5节),它扩展了直接封闭的枚举类型."

  • @edutesoy:JLS 8.9枚举部分说:"枚举常量的可选类主体隐式定义了一个匿名类声明(第15.9.5节),它扩展了直接封闭的枚举类型." 但我引用它是错误的......你当然可以从你的匿名类本身引用这些方法.它也应该可以通过反射来引用它,如果你猜出匿名类的名称(最后它不是那么匿名),也许也可以通过((Enum $ 0)A).method()...不是我会使用它(我甚至不确定它是否有效). (2认同)

Yis*_*hai 5

每个enum都是一个匿名的内部类.因此,与任何匿名内部类一样,您可以添加所需的所有方法,但是没有办法在类之外引用它们,因为类没有定义方法的类型.

允许enum实现方法的优点是它允许策略模式,其中枚举本身具有抽象方法或默认实现,并且具有该方法的实现的特定成员enum可以做出不同的事情.

我已经使用这种技术大大降低了switch语句的代码复杂性.不要在其他类中打开枚举,只需获取对它的引用并调用方法,然后让枚举本身处理它.当然,这取决于场景是否有意义,但它可以极大地降低代码复杂性.