• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package java.lang;
18 
19 import java.io.Serializable;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import libcore.util.BasicLruCache;
23 import libcore.util.EmptyArray;
24 
25 /**
26  * The superclass of all enumerated types. Actual enumeration types inherit from
27  * this class, but extending this class does not make a class an enumeration
28  * type, since the compiler needs to generate special information for it.
29  */
30 public abstract class Enum<E extends Enum<E>> implements Serializable, Comparable<E> {
31 
32     private static final long serialVersionUID = -4300926546619394005L;
33 
34     private static final BasicLruCache<Class<? extends Enum>, Object[]> sharedConstantsCache
35             = new BasicLruCache<Class<? extends Enum>, Object[]>(64) {
36         @Override protected Object[] create(Class<? extends Enum> enumType) {
37             Method method = (Method) Class.getDeclaredConstructorOrMethod(
38                     enumType, "values", EmptyArray.CLASS);
39             try {
40                 return (Object[]) method.invoke((Object[]) null);
41             } catch (IllegalAccessException impossible) {
42                 throw new AssertionError();
43             } catch (InvocationTargetException impossible) {
44                 throw new AssertionError();
45             }
46         }
47     };
48 
49     private final String name;
50 
51     private final int ordinal;
52 
53     /**
54      * Constructor for constants of enum subtypes.
55      *
56      * @param name
57      *            the enum constant's declared name.
58      * @param ordinal
59      *            the enum constant's ordinal, which corresponds to its position
60      *            in the enum declaration, starting at zero.
61      */
Enum(String name, int ordinal)62     protected Enum(String name, int ordinal) {
63         this.name = name;
64         this.ordinal = ordinal;
65     }
66 
67     /**
68      * Returns the name of this enum constant. The name is the field as it
69      * appears in the {@code enum} declaration.
70      *
71      * @return the name of this enum constant.
72      * @see #toString()
73      */
name()74     public final String name() {
75         return name;
76     }
77 
78     /**
79      * Returns the position of the enum constant in the declaration. The first
80      * constant has an ordinal value of zero.
81      *
82      * @return the ordinal value of this enum constant.
83      */
ordinal()84     public final int ordinal() {
85         return ordinal;
86     }
87 
88     /**
89      * Returns a string containing a concise, human-readable description of this
90      * object. In this case, the enum constant's name is returned.
91      *
92      * @return a printable representation of this object.
93      */
94     @Override
toString()95     public String toString() {
96         return name;
97     }
98 
99     /**
100      * Compares this object with the specified object and indicates if they are
101      * equal. In order to be equal, {@code object} must be identical to this
102      * enum constant.
103      *
104      * @param other
105      *            the object to compare this enum constant with.
106      * @return {@code true} if the specified object is equal to this
107      *         {@code Enum}; {@code false} otherwise.
108      */
109     @Override
equals(Object other)110     public final boolean equals(Object other) {
111         return this == other;
112     }
113 
114     @Override
hashCode()115     public final int hashCode() {
116         return ordinal + (name == null ? 0 : name.hashCode());
117     }
118 
119     /**
120      * {@code Enum} objects are singletons, they may not be cloned. This method
121      * always throws a {@code CloneNotSupportedException}.
122      *
123      * @return does not return.
124      * @throws CloneNotSupportedException
125      *             is always thrown.
126      */
127     @Override
clone()128     protected final Object clone() throws CloneNotSupportedException {
129         throw new CloneNotSupportedException("Enums may not be cloned");
130     }
131 
132     /**
133      * Compares this object to the specified enum object to determine their
134      * relative order. This method compares the object's ordinal values, that
135      * is, their position in the enum declaration.
136      *
137      * @param o
138      *            the enum object to compare this object to.
139      * @return a negative value if the ordinal value of this enum constant is
140      *         less than the ordinal value of {@code o}; 0 if the ordinal
141      *         values of this enum constant and {@code o} are equal; a positive
142      *         value if the ordinal value of this enum constant is greater than
143      *         the ordinal value of {@code o}.
144      * @see java.lang.Comparable
145      */
compareTo(E o)146     public final int compareTo(E o) {
147         return ordinal - o.ordinal;
148     }
149 
150     /**
151      * Returns the enum constant's declaring class.
152      *
153      * @return the class object representing the constant's enum type.
154      */
155     @SuppressWarnings("unchecked")
getDeclaringClass()156     public final Class<E> getDeclaringClass() {
157         Class<?> myClass = getClass();
158         Class<?> mySuperClass = myClass.getSuperclass();
159         if (Enum.class == mySuperClass) {
160             return (Class<E>)myClass;
161         }
162         return (Class<E>)mySuperClass;
163     }
164 
165     /**
166      * Returns the constant with the specified name of the specified enum type.
167      *
168      * @param enumType
169      *            the class of the enumerated type to search for the constant
170      *            value.
171      * @param name
172      *            the name of the constant value to find.
173      * @return the enum constant.
174      * @throws NullPointerException
175      *             if either {@code enumType} or {@code name} are {@code null}.
176      * @throws IllegalArgumentException
177      *             if {@code enumType} is not an enumerated type or does not
178      *             have a constant value called {@code name}.
179      */
valueOf(Class<T> enumType, String name)180     public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
181         if (enumType == null || name == null) {
182             throw new NullPointerException("enumType == null || name == null");
183         }
184         if (!enumType.isEnum()) {
185             throw new IllegalArgumentException(enumType + " is not an enum type");
186         }
187         for (T value : getSharedConstants(enumType)) {
188             if (name.equals(value.name())) {
189                 return value;
190             }
191         }
192         throw new IllegalArgumentException(name + " is not a constant in " + enumType.getName());
193     }
194 
195     /**
196      * Returns a shared, mutable array containing the constants of this enum. It
197      * is an error to modify the returned array.
198      *
199      * @hide
200      */
201     @SuppressWarnings("unchecked") // the cache always returns the type matching enumType
getSharedConstants(Class<T> enumType)202     public static <T extends Enum<T>> T[] getSharedConstants(Class<T> enumType) {
203         return (T[]) sharedConstantsCache.get(enumType);
204     }
205 
206     /**
207      * Enum types may not have finalizers.
208      *
209      * @since 1.6
210      */
211     @Override
212     @SuppressWarnings("FinalizeDoesntCallSuperFinalize")
finalize()213     protected final void finalize() {
214     }
215 }
216