Java Enum definition

后端 未结 7 660
孤独总比滥情好
孤独总比滥情好 2020-11-22 17:24

I thought I understood Java generics pretty well, but then I came across the following in java.lang.Enum:

class Enum>
         


        
7条回答
  •  佛祖请我去吃肉
    2020-11-22 17:44

    If you look at the Enum source code, it has the following:

    public abstract class Enum>
            implements Comparable, Serializable {
    
        public final int compareTo(E o) {
            Enum other = (Enum)o;
            Enum self = this;
            if (self.getClass() != other.getClass() && // optimization
                self.getDeclaringClass() != other.getDeclaringClass())
                throw new ClassCastException();
            return self.ordinal - other.ordinal;
        }
    
        @SuppressWarnings("unchecked")
        public final Class getDeclaringClass() {
            Class clazz = getClass();
            Class zuper = clazz.getSuperclass();
            return (zuper == Enum.class) ? (Class)clazz : (Class)zuper;
        }
    
        public static > T valueOf(Class enumType,
                                                    String name) {
            T result = enumType.enumConstantDirectory().get(name);
            if (result != null)
                return result;
            if (name == null)
                throw new NullPointerException("Name is null");
            throw new IllegalArgumentException(
                "No enum constant " + enumType.getCanonicalName() + "." + name);
        } 
    }
    

    First thing first, what does E extends Enum mean? It means the type parameter is something that extends from Enum, and isn't parametrized with a raw type (it's parametrized by itself).

    This is relevant if you have an enum

    public enum MyEnum {
        THING1,
        THING2;
    }
    

    which, if I know correctly, is translated to

    public final class MyEnum extends Enum {
        public static final MyEnum THING1 = new MyEnum();
        public static final MyEnum THING2 = new MyEnum();
    }
    

    So this means that MyEnum receives the following methods:

    public final int compareTo(MyEnum o) {
        Enum other = (Enum)o;
        Enum self = this;
        if (self.getClass() != other.getClass() && // optimization
            self.getDeclaringClass() != other.getDeclaringClass())
            throw new ClassCastException();
        return self.ordinal - other.ordinal;
    }
    

    And even more importantly,

        @SuppressWarnings("unchecked")
        public final Class getDeclaringClass() {
            Class clazz = getClass();
            Class zuper = clazz.getSuperclass();
            return (zuper == Enum.class) ? (Class)clazz : (Class)zuper;
        }
    

    This makes getDeclaringClass() cast to the proper Class object.

    A way clearer example is the one that I answered on this question where you cannot avoid this construct if you want to specify a generic bound.

提交回复
热议问题