我在做一些实验时不小心写了一段代码,这很奇怪,我不明白。我什至很惊讶我能编译它。它看起来像这样:
enum Foo {
VALUE_1 {
public int myVariable = 1;
},
VALUE_2 {
public void myMethod() {
//
}
},
VALUE_3;
}
正如预期的那样,不可能通过以下方式访问这样的元素:
Foo.VALUE_2.myMethod();
原因是,编译器将在枚举本身内部查找该方法。
我认为不可能从枚举外部访问这些方法和变量。因此,我尝试创建一个参数构造函数并使用一些内部变量调用它:
enum Foo {
VALUE(internalVariable) {
int internalVariable = 1;
};
private Foo(int param) {
//
}
}
不可能编译这样的结构。现在我在想,如果无法访问常量中的某些内容,那么定义它有什么意义。
我试图在常量以及枚举本身中创建同名的方法,以检查它是否以某种方式发生冲突。没有!
enum Foo {
VALUE_1 {
int myVariable = 1;
public int myMethod() {
return myVariable;
}
},
VALUE_2 {
//
};
public int myMethod() {
return 0;
}
}
有趣的时刻来了!我尝试在枚举中继续调用 myMethod(),并实际弄清楚了这个 Java 魔法是如何工作的。在常量内部定义的方法会覆盖在枚举内部定义的方法。
Foo.VALUE_1.myMethod(); // Returns 1
Foo.VALUE_2.myMethod(); // Returns 0
但是,我们不能覆盖变量,对吧?所以我很好奇,它如何仅适用于变量。
enum Foo {
VALUE_1 {
public int myVariable = 1;
},
VALUE_2 {
//
};
public int myVariable = 0;
}
....
System.out.println(Foo.VALUE_1.myVariable); // Returns 0
System.out.println(Foo.VALUE_2.myVariable); // Returns 0
现在我终于回答我的问题了:
-
为什么我创建时没有收到任何错误公共方法在常量内部并将枚举留空而没有此方法?在这种情况下,我刚刚定义的方法不能被调用根本不。还是我错了?
Update:我知道枚举可以实现接口。但是,如果我没有
具体来说,整个代码毫无意义。
有人指出,即使无法从正常的语言访问方法
方式,仍然可以使用反射。好吧...为什么我们不设计一个难以接近的关键词?
inaccessible void magicalMethod() {
//
}
这样的方法会被编译到*.class文件中。当你想使用它时,你必须
自己加载字节码并解释它。
我只是不明白,为什么可以定义无法访问的方法。唯一的原因
我可以认为程序员正在工作并且还没有接口的定义。所以
他只是准备单个方法的代码,稍后将添加“implements”关键字。旁
这是不合逻辑的,它仍然需要在所有常量中都有这样的方法。
我认为这应该以错误结束,而不仅仅是警告未使用的方法。你可能会忘记
添加“implement”子句或在枚举中定义方法(这将是
被覆盖)并且在第一次使用后就会意识到这一点。 Java是一种非常严格的语言,
所以我期望这种行为。
-
为什么我创建时没有收到任何错误公共变量(更准确地说,是场)在常量内?无论如何(从外部)都无法访问它。因此,修饰语“public”在这里没有任何意义。
Update:除了可见性之外,它与上一点不太相同
修改器在这里完全没用。是否公开、受保护并不重要
或私有的,因为无论如何你都无法访问它。我认为这是一个错误。
-
为什么可以定义一个类(没有可见性修饰符),但是不是接口?是的,您可能不想编写如此残酷的枚举,以至于您需要在常量中定义类,甚至在那里使用继承。但如果可以定义类和抽象类,那就没什么奇怪的了。
Update:这绝对不是你经常需要的东西,但我理解
它可能有用。但为什么它仅限于类而不能是接口
也定义了?
enum Foo {
VALUE {
class MyClass {
// OK
}
abstract class MyAbstractClass {
// OK
}
interface MyInterface {
// FAIL. It won't compile.
}
}
}
-
您在某处使用过这样的功能吗?我可以想象它可能有用,但有点令人困惑。另外,当我搜索相关资源时,我没有找到任何内容。
Update:我想看到一些在枚举常量类主体中重写方法的实际示例。你在一些开源项目中见过它吗?
环境:
$ java -version
java version "1.7.0_21"
OpenJDK Runtime Environment (IcedTea 2.3.9) (7u21-2.3.9-0ubuntu0.12.10.1)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
感谢您的宝贵时间和您的回答!