Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 枚举:每个实例的独占方法_Java_Compiler Construction_Syntax_Enums - Fatal编程技术网

Java 枚举:每个实例的独占方法

Java 枚举:每个实例的独占方法,java,compiler-construction,syntax,enums,Java,Compiler Construction,Syntax,Enums,从中我了解到,在Java中,可以为枚举的每个实例定义特定的方法: 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; } }

从中我了解到,在Java中,可以为枚举的每个实例定义特定的方法:

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; } } ;
    }

    ...
}
我感到惊讶的是,这甚至是可能的,这个特定于每个实例的“独占方法”是否有一个名称来查找文档

还有,应该如何使用它?因为下一步不是编译:

    private void myMethod () {
        MyEnum.A.method1();
    }

如何使用这些“独占”方法?

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

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);
        }
    }
}

您不能引用这些方法,因为您正在为每个枚举有效地创建匿名(*)类。由于它是匿名的,所以只能从匿名类本身内部或通过反射引用此类方法

当您在枚举中声明抽象方法并分别为每个枚举实现该方法时,此技术最为有用


(*)JLS 8.9 enum部分说:“enum常量的可选类体隐式定义了一个匿名类声明(§15.9.5),该声明扩展了立即封闭的enum类型。”

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

允许在
enum
实现上使用方法的优点是,它允许策略模式,其中enum本身具有抽象方法或默认实现,并且
enum
的特定成员具有该方法的实现,这些实现可能会做一些不同的事情


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

如果他希望所有实例共享一个方法,但有单独的实现,根据我收集的信息,我认为情况并非如此。没错,我希望每个实例都有“特定的方法”,因为java似乎允许它。。。在我看来,这个答案并没有回答我提出的两个问题中的任何一个。@Sanjay:终于有了一个有意义的答案@edutesoy:如果您希望针对每个枚举实现特定的方法(即,每个枚举的
doCalc
不同),请使用我提供的方法。否则,您可以在枚举上使用普通方法(不放在特定的枚举实例中),所有枚举实例都可以访问这些方法。@Sanjay,我否决了它,因为它不符合我的答案,请您修改您的答案以满足我提出的问题好吗?特别是,如何访问MyEnum.A.method1();(或对其不可能的某些解释)而不修改Enum(在Java语言中似乎是合法的)。只是想更好地理解枚举,而不是面对任何实际问题。我很乐意接受。谢谢!那么,为什么Java允许这样做呢?你有没有提到过这种特殊性?@edutesoy:JLS 8.9 Enums part说:“enum常量的可选类体隐式定义了一个匿名类声明(§15.9.5),该声明扩展了立即封闭的enum类型。”但我引用它是错误的。。。当然,您可以从匿名类本身内部引用此类方法。还应该可以通过反射引用它,如果您猜到匿名类的名称(最终不是那么匿名),也可以通过((Enum$0)A).method()引用它。。。并不是说我会用它(我甚至不确定它是否有效)。我建议你在回答中添加最后一条评论。我会接受的。谢谢@edutesoy:好的,是这样的。我对我的答案稍加修改,以使其仍然有意义;不编译,因为编译器只知道MyEnum.A是MyEnum类型,并且您尚未为此枚举声明任何方法。您要查找的“名称”是枚举定义中的任意一个类。@彼得:对不起,我在完成之前发布了注释。@安德烈亚斯:我已经删除了我的过时注释:)请注意,虽然目前不可能这样做,但在将来的Java版本中,它也会作为一个匿名的内部类出现在表中。。。没有办法在课堂之外引用它们。它是匿名的这一事实是一个技术问题;您仍然可以通过其隐式类型访问该方法:
newobject(){public void foo(){}}.foo()。我看不出为什么枚举常量在直接引用时不能以相同的方式工作。