起因是听课到
该段的输出boy输出什么?
答案就是输出BOY,但韩老师解释的有点笼统。
但是我看了一眼源码关于这个name确实有点没头绪
- public abstract class Enum
extends Enum> - implements Comparable
, Serializable { - /**
- * The name of this enum constant, as declared in the enum declaration.
- * Most programmers should use the {@link #toString} method rather than
- * accessing this field.
- */
- //在enum声明中声明的枚举常量的名称。大多数程序员应该使用{@link #toString}方法,而不是直接访问这个字段。
- private final String name;
- /**
- * Returns the name of this enum constant, exactly as declared in its
- * enum declaration.
- *
- * Most programmers should use the {@link #toString} method in
- * preference to this one, as the toString method may return
- * a more user-friendly name. This method is designed primarily for
- * use in specialized situations where correctness depends on getting the
- * exact name, which will not vary from release to release.
- *
- * @return the name of this enum constant
- */
- //返回这个枚举常量的名称,与enum声明中的名称完全一致。大多数程序员应该优先使用{@link #toString}方法,因为toString方法可能会返回一个更友好的名称。这个方法主要是为特殊情况设计的,在这种情况下,正确性取决于准确的名称,不同版本的名称不会有变化。@返回这个枚举常量的名称
- public final String name() {
- return name;
- }
- /**
- * Sole constructor. Programmers cannot invoke this constructor.
- * It is for use by code emitted by the compiler in response to
- * enum type declarations.
- *
- * @param name - The name of this enum constant, which is the identifier
- * used to declare it.
- * @param ordinal - The ordinal of this enumeration constant (its position
- * in the enum declaration, where the initial constant is assigned
- * an ordinal of zero).
- */
- //唯一的构造函数。程序员不能调用这个构造函数。它由编译器响应enum类型声明而发出的代码使用。
-
- //* @param name——这个枚举常量的名称,是用来声明它的标识符。
-
- //* @param ordinal—枚举常量的序号(它的位置
-
- //*在枚举声明中,初始常量被赋值为0)。
- protected Enum(String name, int ordinal) {
- this.name = name;
- this.ordinal = ordinal;
- }
- /**
- * Returns the name of this enum constant, as contained in the
- * declaration. This method may be overridden, though it typically
- * isn't necessary or desirable. An enum type should override this
- * method when a more "programmer-friendly" string form exists.
- *
- * @return the name of this enum constant
- */
- //返回这个枚举常量的名称,正如声明中所包含的。这个方法可能会被重写,尽管它通常不是必要的或理想的。如果存在对程序员更友好的字符串形式,enum类型应该覆盖这个方法。
- //@返回这个枚举常量的名称
- public String toString() {
- return name;
- }
源码的注释解释的倒是蛮清楚
翻译如下
//在enum声明中声明的枚举常量的名称。大多数程序员应该使用{@link #toString}方法,而不是直接访问这个字段。
//返回这个枚举常量的名称,与enum声明中的名称完全一致。大多数程序员应该优先使用{@link #toString}方法,因为toString方法可能会返回一个更友好的名称。这个方法主要是为特殊情况设计的,在这种情况下,正确性取决于准确的名称,不同版本的名称不会有变化。@返回这个枚举常量的名称
//唯一的构造函数。程序员不能调用这个构造函数。它由编译器响应enum类型声明而发出的代码使用。
//返回这个枚举常量的名称,正如声明中所包含的。这个方法可能会被重写,尽管它通常不是必要的或理想的。如果存在对程序员更友好的字符串形式,enum类型应该覆盖这个方法。
//@返回这个枚举常量的名称
解决:其实重要的是这一句话Sole constructor. Programmers cannot invoke this constructor.It is for use by code emitted by the compiler in response to enum type declarations.
也就是说compiler编译器执行了这一段抽象类的构造器使用,所以在源码中我们是看不见这个String name形式参数是哪一个实际参数传入的,只能知道的是代码运行时,该类被使用(因为程序员写的比如enmu XXX{}实际上是继承了该类)的时候就传入了,而且能确定的是如果子类型enmu XXX{}没有重写,那么这里toString返回的name就是常量名字。
不过确实,随着编译器版本的不同,这个name也不同。
总结:编译器执行了构造方法的实参的传入,没有显式的表现;传入的时间在代码运行时,该类被使用了,就会创建对象空间
关于enmu 类的枚举可以参考
还有个rz问题,刚刚我在想为什么enmu Season{}在系统中能默认继承为abstract的Enmu,突然想起来,Enmu类内并没有抽象方法,所以是可以被继承的,就跟下面这个一样。