【疑问解决】- 源码Enmu枚举类的toString里面的name是哪里来的,什么时候传入的?

起因是听课到

                

该段的输出boy输出什么?

答案就是输出BOY,但韩老师解释的有点笼统。

但是我看了一眼源码关于这个name确实有点没头绪

public abstract class 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 类的枚举可以参考

小谈Java Enum的多态性 - Perifort Pro. - ITeye博客

https://www.cnblogs.com/xiangguoguo/p/9061678.html

还有个rz问题,刚刚我在想为什么enmu Season{}在系统中能默认继承为abstract的Enmu,突然想起来,Enmu类内并没有抽象方法,所以是可以被继承的,就跟下面这个一样。

                【疑问解决】- 源码Enmu枚举类的toString里面的name是哪里来的,什么时候传入的?_第1张图片 

你可能感兴趣的:(1024程序员节,java,学习)