96 * </pre></blockquote> 97 * 98 * <p> It is also possible to get the {@code Class} object for a named 99 * type (or for void) using a class literal. See Section 15.8.2 of 100 * <cite>The Java™ Language Specification</cite>. 101 * For example: 102 * 103 * <p> <blockquote> 104 * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());} 105 * </blockquote> 106 * 107 * @param <T> the type of the class modeled by this {@code Class} 108 * object. For example, the type of {@code String.class} is {@code 109 * Class<String>}. Use {@code Class<?>} if the class being modeled is 110 * unknown. 111 * 112 * @author unascribed 113 * @see java.lang.ClassLoader#defineClass(byte[], int, int) 114 * @since JDK1.0 115 */ 116 public final 117 class Class<T> implements java.io.Serializable, 118 java.lang.reflect.GenericDeclaration, 119 java.lang.reflect.Type, 120 java.lang.reflect.AnnotatedElement { 121 private static final int ANNOTATION= 0x00002000; 122 private static final int ENUM = 0x00004000; 123 private static final int SYNTHETIC = 0x00001000; 124 125 private static native void registerNatives(); 126 static { 127 registerNatives(); 128 } 129 130 /* 131 * Constructor. Only the Java Virtual Machine creates Class 132 * objects. 133 */ 134 private Class() {} 135 136 137 /** 138 * Converts the object to a string. The string representation is the 139 * string "class" or "interface", followed by a space, and then by the 140 * fully qualified name of the class in the format returned by 141 * {@code getName}. If this {@code Class} object represents a 142 * primitive type, this method returns the name of the primitive type. If 143 * this {@code Class} object represents void this method returns 144 * "void". 145 * 146 * @return a string representation of this class object. 147 */ 148 public String toString() { 149 return (isInterface() ? "interface " : (isPrimitive() ? "" : "class ")) 150 + getName(); 151 } 152 153 154 /** 155 * Returns the {@code Class} object associated with the class or 156 * interface with the given string name. Invoking this method is 157 * equivalent to: 158 * 159 * <blockquote> 160 * {@code Class.forName(className, true, currentLoader)} 161 * </blockquote> 162 * 163 * where {@code currentLoader} denotes the defining class loader of 164 * the current class. 165 * 166 * <p> For example, the following code fragment returns the 167 * runtime {@code Class} descriptor for the class named 168 * {@code java.lang.Thread}: 169 * 170 * <blockquote> 171 * {@code Class t = Class.forName("java.lang.Thread")} 172 * </blockquote> 1144 // name of the immediately enclosing class followed by a '$' followed by: 1145 // (for nested and inner classes): the simple name. 1146 // (for local classes): 1 or more digits followed by the simple name. 1147 // (for anonymous classes): 1 or more digits. 1148 1149 // Since getSimpleBinaryName() will strip the binary name of 1150 // the immediatly enclosing class, we are now looking at a 1151 // string that matches the regular expression "\$[0-9]*" 1152 // followed by a simple name (considering the simple of an 1153 // anonymous class to be the empty string). 1154 1155 // Remove leading "\$[0-9]*" from the name 1156 int length = simpleName.length(); 1157 if (length < 1 || simpleName.charAt(0) != '$') 1158 throw new InternalError("Malformed class name"); 1159 int index = 1; 1160 while (index < length && isAsciiDigit(simpleName.charAt(index))) 1161 index++; 1162 // Eventually, this is the empty string iff this is an anonymous class 1163 return simpleName.substring(index); 1164 } 1165 1166 /** 1167 * Character.isDigit answers {@code true} to some non-ascii 1168 * digits. This one does not. 1169 */ 1170 private static boolean isAsciiDigit(char c) { 1171 return '0' <= c && c <= '9'; 1172 } 1173 1174 /** 1175 * Returns the canonical name of the underlying class as 1176 * defined by the Java Language Specification. Returns null if 1177 * the underlying class does not have a canonical name (i.e., if 1178 * it is a local or anonymous class or an array whose component 1179 * type does not have a canonical name). 1180 * @return the canonical name of the underlying class if it exists, and 1181 * {@code null} otherwise. 1182 * @since 1.5 1183 */ | 96 * </pre></blockquote> 97 * 98 * <p> It is also possible to get the {@code Class} object for a named 99 * type (or for void) using a class literal. See Section 15.8.2 of 100 * <cite>The Java™ Language Specification</cite>. 101 * For example: 102 * 103 * <p> <blockquote> 104 * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());} 105 * </blockquote> 106 * 107 * @param <T> the type of the class modeled by this {@code Class} 108 * object. For example, the type of {@code String.class} is {@code 109 * Class<String>}. Use {@code Class<?>} if the class being modeled is 110 * unknown. 111 * 112 * @author unascribed 113 * @see java.lang.ClassLoader#defineClass(byte[], int, int) 114 * @since JDK1.0 115 */ 116 public final class Class<T> implements java.io.Serializable, 117 java.lang.reflect.GenericDeclaration, 118 java.lang.reflect.Type, 119 java.lang.reflect.AnnotatedElement { 120 private static final int ANNOTATION= 0x00002000; 121 private static final int ENUM = 0x00004000; 122 private static final int SYNTHETIC = 0x00001000; 123 124 private static native void registerNatives(); 125 static { 126 registerNatives(); 127 } 128 129 /* 130 * Constructor. Only the Java Virtual Machine creates Class 131 * objects. 132 */ 133 private Class() {} 134 135 136 /** 137 * Converts the object to a string. The string representation is the 138 * string "class" or "interface", followed by a space, and then by the 139 * fully qualified name of the class in the format returned by 140 * {@code getName}. If this {@code Class} object represents a 141 * primitive type, this method returns the name of the primitive type. If 142 * this {@code Class} object represents void this method returns 143 * "void". 144 * 145 * @return a string representation of this class object. 146 */ 147 public String toString() { 148 return (isInterface() ? "interface " : (isPrimitive() ? "" : "class ")) 149 + getName(); 150 } 151 152 /** 153 * Returns a string describing this {@code Class}, including 154 * information about modifiers and type parameters. 155 * 156 * The string is formatted as a list of type modifiers, if any, 157 * followed by the kind of type (empty string for primitive types 158 * and {@code class}, {@code enum}, {@code interface}, or {@code 159 * @interface}, as appropriate), followed by the type's name, 160 * followed by an angle-bracketed comma-separated list of the 161 * type's type parameters, if any. 162 * 163 * A space is used to separate modifiers from one another and to 164 * separate any modifiers from the kind of type. The modifiers 165 * occur in canonical order. If there are no type parameters, the 166 * type parameter list is elided. 167 * 168 * <p>Note that since information about the runtime representation 169 * of a type is being generated, modifiers not present on the 170 * originating source code or illegal on the originating source 171 * code may be present. 172 * 173 * @return a string describing this {@code Class}, including 174 * information about modifiers and type parameters 175 * 176 * @since 1.8 177 */ 178 public String toGenericString() { 179 if (isPrimitive()) { 180 return toString(); 181 } else { 182 StringBuilder sb = new StringBuilder(); 183 184 // Class modifiers are a superset of interface modifiers 185 int modifiers = getModifiers() & Modifier.classModifiers(); 186 if (modifiers != 0) { 187 sb.append(Modifier.toString(modifiers)); 188 sb.append(' '); 189 } 190 191 if (isAnnotation()) { 192 sb.append('@'); 193 } 194 if (isInterface()) { // Note: all annotation types are interfaces 195 sb.append("interface"); 196 } else { 197 if (isEnum()) 198 sb.append("enum"); 199 else 200 sb.append("class"); 201 } 202 sb.append(' '); 203 sb.append(getName()); 204 205 TypeVariable<?>[] typeparms = getTypeParameters(); 206 if (typeparms.length > 0) { 207 boolean first = true; 208 sb.append('<'); 209 for(TypeVariable<?> typeparm: typeparms) { 210 if (!first) 211 sb.append(','); 212 sb.append(typeparm.getTypeName()); 213 first = false; 214 } 215 sb.append('>'); 216 } 217 218 return sb.toString(); 219 } 220 } 221 222 /** 223 * Returns the {@code Class} object associated with the class or 224 * interface with the given string name. Invoking this method is 225 * equivalent to: 226 * 227 * <blockquote> 228 * {@code Class.forName(className, true, currentLoader)} 229 * </blockquote> 230 * 231 * where {@code currentLoader} denotes the defining class loader of 232 * the current class. 233 * 234 * <p> For example, the following code fragment returns the 235 * runtime {@code Class} descriptor for the class named 236 * {@code java.lang.Thread}: 237 * 238 * <blockquote> 239 * {@code Class t = Class.forName("java.lang.Thread")} 240 * </blockquote> 1212 // name of the immediately enclosing class followed by a '$' followed by: 1213 // (for nested and inner classes): the simple name. 1214 // (for local classes): 1 or more digits followed by the simple name. 1215 // (for anonymous classes): 1 or more digits. 1216 1217 // Since getSimpleBinaryName() will strip the binary name of 1218 // the immediatly enclosing class, we are now looking at a 1219 // string that matches the regular expression "\$[0-9]*" 1220 // followed by a simple name (considering the simple of an 1221 // anonymous class to be the empty string). 1222 1223 // Remove leading "\$[0-9]*" from the name 1224 int length = simpleName.length(); 1225 if (length < 1 || simpleName.charAt(0) != '$') 1226 throw new InternalError("Malformed class name"); 1227 int index = 1; 1228 while (index < length && isAsciiDigit(simpleName.charAt(index))) 1229 index++; 1230 // Eventually, this is the empty string iff this is an anonymous class 1231 return simpleName.substring(index); 1232 } 1233 1234 /** 1235 * Return an informative string for the name of this type. 1236 * 1237 * @return an informative string for the name of this type 1238 * @since 1.8 1239 */ 1240 public String getTypeName() { 1241 if (isArray()) { 1242 try { 1243 Class<?> cl = this; 1244 int dimensions = 0; 1245 while (cl.isArray()) { 1246 dimensions++; 1247 cl = cl.getComponentType(); 1248 } 1249 StringBuilder sb = new StringBuilder(); 1250 sb.append(cl.getName()); 1251 for (int i = 0; i < dimensions; i++) { 1252 sb.append("[]"); 1253 } 1254 return sb.toString(); 1255 } catch (Throwable e) { /*FALLTHRU*/ } 1256 } 1257 return getName(); 1258 } 1259 1260 /** 1261 * Character.isDigit answers {@code true} to some non-ascii 1262 * digits. This one does not. 1263 */ 1264 private static boolean isAsciiDigit(char c) { 1265 return '0' <= c && c <= '9'; 1266 } 1267 1268 /** 1269 * Returns the canonical name of the underlying class as 1270 * defined by the Java Language Specification. Returns null if 1271 * the underlying class does not have a canonical name (i.e., if 1272 * it is a local or anonymous class or an array whose component 1273 * type does not have a canonical name). 1274 * @return the canonical name of the underlying class if it exists, and 1275 * {@code null} otherwise. 1276 * @since 1.5 1277 */ |