1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.lang; 28 29 import java.io.Serializable; 30 import java.io.IOException; 31 import java.io.InvalidObjectException; 32 import java.io.ObjectInputStream; 33 import java.io.ObjectStreamException; 34 import java.lang.reflect.InvocationTargetException; 35 import java.lang.reflect.Method; 36 import libcore.util.BasicLruCache; 37 import libcore.util.EmptyArray; 38 39 /** 40 * This is the common base class of all Java language enumeration types. 41 * 42 * More information about enums, including descriptions of the 43 * implicitly declared methods synthesized by the compiler, can be 44 * found in section 8.9 of 45 * <cite>The Java™ Language Specification</cite>. 46 * 47 * <p> Note that when using an enumeration type as the type of a set 48 * or as the type of the keys in a map, specialized and efficient 49 * {@linkplain java.util.EnumSet set} and {@linkplain 50 * java.util.EnumMap map} implementations are available. 51 * 52 * @param <E> The enum type subclass 53 * @author Josh Bloch 54 * @author Neal Gafter 55 * @see Class#getEnumConstants() 56 * @see java.util.EnumSet 57 * @see java.util.EnumMap 58 * @since 1.5 59 */ 60 public abstract class Enum<E extends Enum<E>> 61 implements Comparable<E>, Serializable { 62 /** 63 * The name of this enum constant, as declared in the enum declaration. 64 * Most programmers should use the {@link #toString} method rather than 65 * accessing this field. 66 */ 67 private final String name; 68 69 /** 70 * Returns the name of this enum constant, exactly as declared in its 71 * enum declaration. 72 * 73 * <b>Most programmers should use the {@link #toString} method in 74 * preference to this one, as the toString method may return 75 * a more user-friendly name.</b> This method is designed primarily for 76 * use in specialized situations where correctness depends on getting the 77 * exact name, which will not vary from release to release. 78 * 79 * @return the name of this enum constant 80 */ name()81 public final String name() { 82 return name; 83 } 84 85 /** 86 * The ordinal of this enumeration constant (its position 87 * in the enum declaration, where the initial constant is assigned 88 * an ordinal of zero). 89 * 90 * Most programmers will have no use for this field. It is designed 91 * for use by sophisticated enum-based data structures, such as 92 * {@link java.util.EnumSet} and {@link java.util.EnumMap}. 93 */ 94 private final int ordinal; 95 96 /** 97 * Returns the ordinal of this enumeration constant (its position 98 * in its enum declaration, where the initial constant is assigned 99 * an ordinal of zero). 100 * 101 * Most programmers will have no use for this method. It is 102 * designed for use by sophisticated enum-based data structures, such 103 * as {@link java.util.EnumSet} and {@link java.util.EnumMap}. 104 * 105 * @return the ordinal of this enumeration constant 106 */ ordinal()107 public final int ordinal() { 108 return ordinal; 109 } 110 111 /** 112 * Sole constructor. Programmers cannot invoke this constructor. 113 * It is for use by code emitted by the compiler in response to 114 * enum type declarations. 115 * 116 * @param name - The name of this enum constant, which is the identifier 117 * used to declare it. 118 * @param ordinal - The ordinal of this enumeration constant (its position 119 * in the enum declaration, where the initial constant is assigned 120 * an ordinal of zero). 121 */ Enum(String name, int ordinal)122 protected Enum(String name, int ordinal) { 123 this.name = name; 124 this.ordinal = ordinal; 125 } 126 127 /** 128 * Returns the name of this enum constant, as contained in the 129 * declaration. This method may be overridden, though it typically 130 * isn't necessary or desirable. An enum type should override this 131 * method when a more "programmer-friendly" string form exists. 132 * 133 * @return the name of this enum constant 134 */ toString()135 public String toString() { 136 return name; 137 } 138 139 /** 140 * Returns true if the specified object is equal to this 141 * enum constant. 142 * 143 * @param other the object to be compared for equality with this object. 144 * @return true if the specified object is equal to this 145 * enum constant. 146 */ equals(Object other)147 public final boolean equals(Object other) { 148 return this==other; 149 } 150 151 /** 152 * Returns a hash code for this enum constant. 153 * 154 * @return a hash code for this enum constant. 155 */ hashCode()156 public final int hashCode() { 157 return super.hashCode(); 158 } 159 160 /** 161 * Throws CloneNotSupportedException. This guarantees that enums 162 * are never cloned, which is necessary to preserve their "singleton" 163 * status. 164 * 165 * @return (never returns) 166 */ clone()167 protected final Object clone() throws CloneNotSupportedException { 168 throw new CloneNotSupportedException(); 169 } 170 171 /** 172 * Compares this enum with the specified object for order. Returns a 173 * negative integer, zero, or a positive integer as this object is less 174 * than, equal to, or greater than the specified object. 175 * 176 * Enum constants are only comparable to other enum constants of the 177 * same enum type. The natural order implemented by this 178 * method is the order in which the constants are declared. 179 */ compareTo(E o)180 public final int compareTo(E o) { 181 Enum other = (Enum)o; 182 Enum self = this; 183 if (self.getClass() != other.getClass() && // optimization 184 self.getDeclaringClass() != other.getDeclaringClass()) 185 throw new ClassCastException(); 186 return self.ordinal - other.ordinal; 187 } 188 189 /** 190 * Returns the Class object corresponding to this enum constant's 191 * enum type. Two enum constants e1 and e2 are of the 192 * same enum type if and only if 193 * e1.getDeclaringClass() == e2.getDeclaringClass(). 194 * (The value returned by this method may differ from the one returned 195 * by the {@link Object#getClass} method for enum constants with 196 * constant-specific class bodies.) 197 * 198 * @return the Class object corresponding to this enum constant's 199 * enum type 200 */ getDeclaringClass()201 public final Class<E> getDeclaringClass() { 202 Class clazz = getClass(); 203 Class zuper = clazz.getSuperclass(); 204 return (zuper == Enum.class) ? clazz : zuper; 205 } 206 207 /** 208 * Returns the enum constant of the specified enum type with the 209 * specified name. The name must match exactly an identifier used 210 * to declare an enum constant in this type. (Extraneous whitespace 211 * characters are not permitted.) 212 * 213 * <p>Note that for a particular enum type {@code T}, the 214 * implicitly declared {@code public static T valueOf(String)} 215 * method on that enum may be used instead of this method to map 216 * from a name to the corresponding enum constant. All the 217 * constants of an enum type can be obtained by calling the 218 * implicit {@code public static T[] values()} method of that 219 * type. 220 * 221 * @param <T> The enum type whose constant is to be returned 222 * @param enumType the {@code Class} object of the enum type from which 223 * to return a constant 224 * @param name the name of the constant to return 225 * @return the enum constant of the specified enum type with the 226 * specified name 227 * @throws IllegalArgumentException if the specified enum type has 228 * no constant with the specified name, or the specified 229 * class object does not represent an enum type 230 * @throws NullPointerException if {@code enumType} or {@code name} 231 * is null 232 * @since 1.5 233 */ valueOf(Class<T> enumType, String name)234 public static <T extends Enum<T>> T valueOf(Class<T> enumType, 235 String name) { 236 if (enumType == null) 237 throw new NullPointerException("enumType == null"); 238 if (name == null) 239 throw new NullPointerException("Name is null"); 240 T[] values = getSharedConstants(enumType); 241 T result = null; 242 if (values != null) { 243 for (T value : values) { 244 if (name.equals(value.name())) { 245 result = value; 246 } 247 } 248 } else { 249 throw new IllegalArgumentException(enumType.toString() + " is not an enum type."); 250 } 251 252 if (result != null) 253 return result; 254 throw new IllegalArgumentException( 255 "No enum constant " + enumType.getCanonicalName() + "." + name); 256 } 257 258 private static final BasicLruCache<Class<? extends Enum>, Object[]> sharedConstantsCache 259 = new BasicLruCache<Class<? extends Enum>, Object[]>(64) { 260 @Override protected Object[] create(Class<? extends Enum> enumType) { 261 if (!enumType.isEnum()) { 262 return null; 263 } 264 try { 265 Method method = enumType.getDeclaredMethod("values", EmptyArray.CLASS); 266 method.setAccessible(true); 267 return (Object[]) method.invoke((Object[]) null); 268 } catch (NoSuchMethodException impossible) { 269 throw new AssertionError("impossible", impossible); 270 } catch (IllegalAccessException impossible) { 271 throw new AssertionError("impossible", impossible); 272 } catch (InvocationTargetException impossible) { 273 throw new AssertionError("impossible", impossible); 274 } 275 } 276 }; 277 278 /** 279 * Returns a shared, mutable array containing the constants of this enum. It 280 * is an error to modify the returned array. 281 * 282 * @hide 283 */ 284 @SuppressWarnings("unchecked") // the cache always returns the type matching enumType getSharedConstants(Class<T> enumType)285 public static <T extends Enum<T>> T[] getSharedConstants(Class<T> enumType) { 286 return (T[]) sharedConstantsCache.get(enumType); 287 } 288 289 /** 290 * enum classes cannot have finalize methods. 291 */ finalize()292 protected final void finalize() { } 293 294 /** 295 * prevent default deserialization 296 */ readObject(ObjectInputStream in)297 private void readObject(ObjectInputStream in) throws IOException, 298 ClassNotFoundException { 299 throw new InvalidObjectException("can't deserialize enum"); 300 } 301 readObjectNoData()302 private void readObjectNoData() throws ObjectStreamException { 303 throw new InvalidObjectException("can't deserialize enum"); 304 } 305 } 306