1 Try 2 { 3 ... ... 4 } 5 catch (Exception ex) 6 { 7 …; 8 throw new Throwable(ex); 9 } 10 catch (Throwable ex) 11 { 12 …; 13 } 14 finally 15 { 16 17 }
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.lang; 19 20 import java.io.IOException; 21 import java.io.ObjectInputStream; 22 import java.io.ObjectOutputStream; 23 import java.io.PrintStream; 24 import java.io.PrintWriter; 25 import java.util.ArrayList; 26 import java.util.List; 27 import libcore.util.EmptyArray; 28 29 /** 30 * The superclass of all classes which can be thrown by the VM. The 31 * two direct subclasses are recoverable exceptions ({@code Exception}) and 32 * unrecoverable errors ({@code Error}). This class provides common methods for 33 * accessing a string message which provides extra information about the 34 * circumstances in which the {@code Throwable} was created (basically an error 35 * message in most cases), and for saving a stack trace (that is, a record of 36 * the call stack at a particular point in time) which can be printed later. 37 * <p> 38 * A {@code Throwable} can also include a cause, which is a nested {@code 39 * Throwable} that represents the original problem that led to this {@code 40 * Throwable}. It is often used for wrapping various types of errors into a 41 * common {@code Throwable} without losing the detailed original error 42 * information. When printing the stack trace, the trace of the cause is 43 * included. 44 * 45 * @see Error 46 * @see Exception 47 * @see RuntimeException 48 */ 49 public class Throwable implements java.io.Serializable { 50 private static final long serialVersionUID = -3042686055658047285L; 51 52 /** 53 * The message provided when the exception was created. 54 */ 55 private String detailMessage; 56 57 /** 58 * The cause of this Throwable. Null when there is no cause. 59 */ 60 private Throwable cause = this; 61 62 /** 63 * Throwables suppressed by this throwable. Null when suppressed exceptions 64 * are disabled. 65 */ 66 private List<Throwable> suppressedExceptions = new ArrayList<Throwable>(); 67 68 /** 69 * An intermediate representation of the stack trace. This field may 70 * be accessed by the VM; do not rename. 71 */ 72 private volatile Object stackState; 73 74 /** 75 * A fully-expanded representation of the stack trace. 76 */ 77 private StackTraceElement[] stackTrace; 78 79 /** 80 * Constructs a new {@code Throwable} that includes the current stack trace. 81 */ 82 public Throwable() { 83 fillInStackTrace(); 84 } 85 86 /** 87 * Constructs a new {@code Throwable} with the current stack trace and the 88 * specified detail message. 89 * 90 * @param detailMessage 91 * the detail message for this {@code Throwable}. 92 */ 93 public Throwable(String detailMessage) { 94 this(); 95 this.detailMessage = detailMessage; 96 } 97 98 /** 99 * Constructs a new {@code Throwable} with the current stack trace, the 100 * specified detail message and the specified cause. 101 * 102 * @param detailMessage 103 * the detail message for this {@code Throwable}. 104 * @param throwable 105 * the cause of this {@code Throwable}. 106 */ 107 public Throwable(String detailMessage, Throwable throwable) { 108 this(); 109 this.detailMessage = detailMessage; 110 cause = throwable; 111 } 112 113 /** 114 * Constructs a new {@code Throwable} with the current stack trace and the 115 * specified cause. 116 * 117 * @param throwable 118 * the cause of this {@code Throwable}. 119 */ 120 public Throwable(Throwable throwable) { 121 this(); 122 this.detailMessage = throwable == null ? null : throwable.toString(); 123 cause = throwable; 124 } 125 126 /** 127 * Constructs a new {@code Throwable} with the current stack trace, the 128 * specified detail message and the specified cause. 129 * 130 * @param enableSuppression if false, throwables passed to {@link 131 * #addSuppressed(Throwable)} will be silently discarded. 132 * @since 1.7 133 * @hide 1.7 134 */ 135 protected Throwable(String detailMessage, Throwable throwable, boolean enableSuppression) { 136 this(detailMessage, throwable); 137 if (!enableSuppression) { 138 this.suppressedExceptions = null; 139 } 140 } 141 142 /** 143 * Records the stack trace from the point where this method has been called 144 * to this {@code Throwable}. This method is invoked by the {@code Throwable} constructors. 145 * 146 * <p>This method is public so that code (such as an RPC system) which catches 147 * a {@code Throwable} and then re-throws it can replace the construction-time stack trace 148 * with a stack trace from the location where the exception was re-thrown, by <i>calling</i> 149 * {@code fillInStackTrace}. 150 * 151 * <p>This method is non-final so that non-Java language implementations can disable VM stack 152 * traces for their language. Filling in the stack trace is relatively expensive. 153 * <i>Overriding</i> this method in the root of a language's exception hierarchy allows the 154 * language to avoid paying for something it doesn't need. 155 * 156 * @return this {@code Throwable} instance. 157 */ 158 public Throwable fillInStackTrace() { 159 // Fill in the intermediate representation 160 stackState = nativeFillInStackTrace(); 161 // Mark the full representation as empty 162 stackTrace = null; 163 return this; 164 } 165 166 /** 167 * Returns the extra information message which was provided when this 168 * {@code Throwable} was created. Returns {@code null} if no message was 169 * provided at creation time. 170 * 171 * @return this {@code Throwable}'s detail message. 172 */ 173 public String getMessage() { 174 return detailMessage; 175 } 176 177 /** 178 * Returns the extra information message which was provided when this 179 * {@code Throwable} was created. Returns {@code null} if no message was 180 * provided at creation time. Subclasses may override this method to return 181 * localized text for the message. Android returns the regular detail message. 182 * 183 * @return this {@code Throwable}'s localized detail message. 184 */ 185 public String getLocalizedMessage() { 186 return getMessage(); 187 } 188 189 /** 190 * Returns the array of stack trace elements of this {@code Throwable}. Each 191 * {@code StackTraceElement} represents an entry in the call stack. The 192 * element at position 0 is the top of the stack, that is, the stack frame 193 * where this {@code Throwable} is thrown. 194 * 195 * @return a copy of the array of {@code StackTraceElement}s representing 196 * the call stack. Changes in the array obtained from this call will 197 * not change the call stack stored in this {@code Throwable}. 198 * @see #printStackTrace() 199 */ 200 public StackTraceElement[] getStackTrace() { 201 return getInternalStackTrace().clone(); 202 } 203 204 /** 205 * Sets the array of stack trace elements. Each {@code StackTraceElement} 206 * represents an entry in the call stack. A copy of the specified array is 207 * stored in this {@code Throwable}. will be returned by {@code 208 * getStackTrace()} and printed by {@code printStackTrace()}. 209 * 210 * @param trace 211 * the new array of {@code StackTraceElement}s. A copy of the 212 * array is stored in this {@code Throwable}, so subsequent 213 * changes to {@code trace} will not change the call stack stored 214 * in this {@code Throwable}. 215 * @throws NullPointerException 216 * if any element in {@code trace} is {@code null}. 217 * @see #printStackTrace() 218 */ 219 public void setStackTrace(StackTraceElement[] trace) { 220 StackTraceElement[] newTrace = trace.clone(); 221 for (StackTraceElement element : newTrace) { 222 if (element == null) { 223 throw new NullPointerException(); 224 } 225 } 226 stackTrace = newTrace; 227 } 228 229 /** 230 * Writes a printable representation of this {@code Throwable}'s stack trace 231 * to the {@code System.err} stream. 232 * 233 */ 234 public void printStackTrace() { 235 printStackTrace(System.err); 236 } 237 238 /** 239 * Counts the number of duplicate stack frames, starting from the 240 * end of the stack. 241 * 242 * @param currentStack a stack to compare 243 * @param parentStack a stack to compare 244 * 245 * @return the number of duplicate stack frames. 246 */ 247 private static int countDuplicates(StackTraceElement[] currentStack, 248 StackTraceElement[] parentStack) { 249 int duplicates = 0; 250 int parentIndex = parentStack.length; 251 for (int i = currentStack.length; --i >= 0 && --parentIndex >= 0;) { 252 StackTraceElement parentFrame = parentStack[parentIndex]; 253 if (parentFrame.equals(currentStack[i])) { 254 duplicates++; 255 } else { 256 break; 257 } 258 } 259 return duplicates; 260 } 261 262 /** 263 * Returns an array of StackTraceElement. Each StackTraceElement 264 * represents a entry on the stack. 265 * 266 * @return an array of StackTraceElement representing the stack 267 */ 268 private StackTraceElement[] getInternalStackTrace() { 269 if (stackTrace == null) { 270 stackTrace = nativeGetStackTrace(stackState); 271 stackState = null; // Clean up intermediate representation 272 } 273 return stackTrace; 274 } 275 276 /** 277 * Writes a printable representation of this {@code Throwable}'s stack trace 278 * to the specified print stream. If the {@code Throwable} contains a 279 * {@link #getCause() cause}, the method will be invoked recursively for 280 * the nested {@code Throwable}. 281 * 282 * @param err 283 * the stream to write the stack trace on. 284 */ 285 public void printStackTrace(PrintStream err) { 286 try { 287 printStackTrace(err, "", null); 288 } catch (IOException e) { 289 // Appendable.append throws IOException but PrintStream.append doesn't. 290 throw new AssertionError(); 291 } 292 } 293 294 /** 295 * Writes a printable representation of this {@code Throwable}'s stack trace 296 * to the specified print writer. If the {@code Throwable} contains a 297 * {@link #getCause() cause}, the method will be invoked recursively for the 298 * nested {@code Throwable}. 299 * 300 * @param err 301 * the writer to write the stack trace on. 302 */ 303 public void printStackTrace(PrintWriter err) { 304 try { 305 printStackTrace(err, "", null); 306 } catch (IOException e) { 307 // Appendable.append throws IOException, but PrintWriter.append doesn't. 308 throw new AssertionError(); 309 } 310 } 311 312 /** 313 * @param indent additional indentation on each line of the stack trace. 314 * This is the empty string for all but suppressed throwables. 315 * @param parentStack the parent stack trace to suppress duplicates from, or 316 * null if this stack trace has no parent. 317 */ 318 private void printStackTrace(Appendable err, String indent, StackTraceElement[] parentStack) 319 throws IOException { 320 err.append(toString()); 321 err.append("\n"); 322 323 StackTraceElement[] stack = getInternalStackTrace(); 324 if (stack != null) { 325 int duplicates = parentStack != null ? countDuplicates(stack, parentStack) : 0; 326 for (int i = 0; i < stack.length - duplicates; i++) { 327 err.append(indent); 328 err.append("\tat "); 329 err.append(stack[i].toString()); 330 err.append("\n"); 331 } 332 333 if (duplicates > 0) { 334 err.append(indent); 335 err.append("\t... "); 336 err.append(Integer.toString(duplicates)); 337 err.append(" more\n"); 338 } 339 } 340 341 // Print suppressed exceptions indented one level deeper. 342 if (suppressedExceptions != null) { 343 for (Throwable throwable : suppressedExceptions) { 344 err.append(indent); 345 err.append("\tSuppressed: "); 346 throwable.printStackTrace(err, indent + "\t", stack); 347 } 348 } 349 350 Throwable cause = getCause(); 351 if (cause != null) { 352 err.append(indent); 353 err.append("Caused by: "); 354 cause.printStackTrace(err, indent, stack); 355 } 356 } 357 358 @Override 359 public String toString() { 360 String msg = getLocalizedMessage(); 361 String name = getClass().getName(); 362 if (msg == null) { 363 return name; 364 } 365 return name + ": " + msg; 366 } 367 368 /** 369 * Initializes the cause of this {@code Throwable}. The cause can only be 370 * initialized once. 371 * 372 * @param throwable 373 * the cause of this {@code Throwable}. 374 * @return this {@code Throwable} instance. 375 * @throws IllegalArgumentException 376 * if {@code Throwable} is this object. 377 * @throws IllegalStateException 378 * if the cause has already been initialized. 379 */ 380 public Throwable initCause(Throwable throwable) { 381 if (cause != this) { 382 throw new IllegalStateException("Cause already initialized"); 383 } 384 if (throwable == this) { 385 throw new IllegalArgumentException("throwable == this"); 386 } 387 cause = throwable; 388 return this; 389 } 390 391 /** 392 * Returns the cause of this {@code Throwable}, or {@code null} if there is 393 * no cause. 394 * 395 * @return Throwable this {@code Throwable}'s cause. 396 */ 397 public Throwable getCause() { 398 if (cause == this) { 399 return null; 400 } 401 return cause; 402 } 403 404 /** 405 * Adds {@code throwable} to the list of throwables suppressed by this. The 406 * throwable will included when this exception's stack trace is printed. 407 * 408 * @throws IllegalArgumentException if {@code throwable == this}. 409 * @throws NullPointerException if {@code throwable == null}. 410 * @since 1.7 411 * @hide 1.7 412 */ 413 public final void addSuppressed(Throwable throwable) { 414 if (throwable == this) { 415 throw new IllegalArgumentException("suppressed == this"); 416 } 417 if (throwable == null) { 418 throw new NullPointerException("suppressed == null"); 419 } 420 if (suppressedExceptions != null) { 421 suppressedExceptions.add(throwable); 422 } 423 } 424 425 /** 426 * Returns the throwables suppressed by this. 427 * 428 * @since 1.7 429 * @hide 1.7 430 */ 431 public final Throwable[] getSuppressed() { 432 return (suppressedExceptions != null) 433 ? suppressedExceptions.toArray(new Throwable[suppressedExceptions.size()]) 434 : EmptyArray.THROWABLE; 435 } 436 437 private void writeObject(ObjectOutputStream out) throws IOException { 438 // ensure the stackTrace field is initialized 439 getInternalStackTrace(); 440 out.defaultWriteObject(); 441 } 442 443 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 444 in.defaultReadObject(); 445 446 if (suppressedExceptions != null) { 447 // the deserialized list may be unmodifiable, so just create a mutable copy 448 suppressedExceptions = new ArrayList<Throwable>(suppressedExceptions); 449 } 450 } 451 452 /* 453 * Creates a compact, VM-specific collection of goodies, suitable for 454 * storing in the "stackState" field, based on the current thread's 455 * call stack. 456 */ 457 private static native Object nativeFillInStackTrace(); 458 459 /* 460 * Creates an array of StackTraceElement objects from the data held 461 * in "stackState". 462 */ 463 private static native StackTraceElement[] nativeGetStackTrace(Object stackState); 464 }
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.lang; 19 20 21 /** 22 * {@code Exception} is the superclass of all classes that represent recoverable 23 * exceptions. When exceptions are thrown, they may be caught by application 24 * code. 25 * 26 * @see Throwable 27 * @see Error 28 * @see RuntimeException 29 */ 30 public class Exception extends Throwable { 31 private static final long serialVersionUID = -3387516993124229948L; 32 33 /** 34 * Constructs a new {@code Exception} that includes the current stack trace. 35 */ 36 public Exception() { 37 } 38 39 /** 40 * Constructs a new {@code Exception} with the current stack trace and the 41 * specified detail message. 42 * 43 * @param detailMessage 44 * the detail message for this exception. 45 */ 46 public Exception(String detailMessage) { 47 super(detailMessage); 48 } 49 50 /** 51 * Constructs a new {@code Exception} with the current stack trace, the 52 * specified detail message and the specified cause. 53 * 54 * @param detailMessage 55 * the detail message for this exception. 56 * @param throwable 57 * the cause of this exception. 58 */ 59 public Exception(String detailMessage, Throwable throwable) { 60 super(detailMessage, throwable); 61 } 62 63 /** 64 * Constructs a new {@code Exception} with the current stack trace and the 65 * specified cause. 66 * 67 * @param throwable 68 * the cause of this exception. 69 */ 70 public Exception(Throwable throwable) { 71 super(throwable); 72 } 73 }
Classjava
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /* 18 * Copyright (C) 2006-2007 The Android Open Source Project 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33 package java.lang; 34 35 import dalvik.system.VMStack; 36 import java.io.InputStream; 37 import java.io.Serializable; 38 import java.lang.annotation.Annotation; 39 import java.lang.annotation.Inherited; 40 import java.lang.reflect.AnnotatedElement; 41 import java.lang.reflect.Constructor; 42 import java.lang.reflect.Field; 43 import java.lang.reflect.GenericDeclaration; 44 import java.lang.reflect.Member; 45 import java.lang.reflect.Method; 46 import java.lang.reflect.Modifier; 47 import java.lang.reflect.Type; 48 import java.lang.reflect.TypeVariable; 49 import java.net.URL; 50 import java.security.ProtectionDomain; 51 import java.util.ArrayList; 52 import java.util.Arrays; 53 import java.util.Collection; 54 import java.util.HashMap; 55 import java.util.List; 56 import libcore.util.CollectionUtils; 57 import libcore.util.EmptyArray; 58 import org.apache.harmony.kernel.vm.StringUtils; 59 import org.apache.harmony.luni.lang.reflect.GenericSignatureParser; 60 import org.apache.harmony.luni.lang.reflect.Types; 61 62 /** 63 * The in-memory representation of a Java class. This representation serves as 64 * the starting point for querying class-related information, a process usually 65 * called "reflection". There are basically three types of {@code Class} 66 * instances: those representing real classes and interfaces, those representing 67 * primitive types, and those representing array classes. 68 * 69 * <h4>Class instances representing object types (classes or interfaces)</h4> 70 * <p> 71 * These represent an ordinary class or interface as found in the class 72 * hierarchy. The name associated with these {@code Class} instances is simply 73 * the fully qualified class name of the class or interface that it represents. 74 * In addition to this human-readable name, each class is also associated by a 75 * so-called <em>signature</em>, which is the letter "L", followed by the 76 * class name and a semicolon (";"). The signature is what the runtime system 77 * uses internally for identifying the class (for example in a DEX file). 78 * </p> 79 * <h4>Classes representing primitive types</h4> 80 * <p> 81 * These represent the standard Java primitive types and hence share their 82 * names (for example "int" for the {@code int} primitive type). Although it is 83 * not possible to create new instances based on these {@code Class} instances, 84 * they are still useful for providing reflection information, and as the 85 * component type of array classes. There is one {@code Class} instance for each 86 * primitive type, and their signatures are: 87 * </p> 88 * <ul> 89 * <li>{@code B} representing the {@code byte} primitive type</li> 90 * <li>{@code S} representing the {@code short} primitive type</li> 91 * <li>{@code I} representing the {@code int} primitive type</li> 92 * <li>{@code J} representing the {@code long} primitive type</li> 93 * <li>{@code F} representing the {@code float} primitive type</li> 94 * <li>{@code D} representing the {@code double} primitive type</li> 95 * <li>{@code C} representing the {@code char} primitive type</li> 96 * <li>{@code Z} representing the {@code boolean} primitive type</li> 97 * <li>{@code V} representing void function return values</li> 98 * </ul> 99 * <p> 100 * <h4>Classes representing array classes</h4> 101 * <p> 102 * These represent the classes of Java arrays. There is one such {@code Class} 103 * instance per combination of array leaf component type and arity (number of 104 * dimensions). In this case, the name associated with the {@code Class} 105 * consists of one or more left square brackets (one per dimension in the array) 106 * followed by the signature of the class representing the leaf component type, 107 * which can be either an object type or a primitive type. The signature of a 108 * {@code Class} representing an array type is the same as its name. Examples 109 * of array class signatures are: 110 * </p> 111 * <ul> 112 * <li>{@code [I} representing the {@code int[]} type</li> 113 * <li>{@code [Ljava/lang/String;} representing the {@code String[]} type</li> 114 * <li>{@code [[[C} representing the {@code char[][][]} type (three dimensions!)</li> 115 * </ul> 116 */ 117 public final class Class<T> implements Serializable, AnnotatedElement, GenericDeclaration, Type { 118 119 private static final long serialVersionUID = 3206093459760846163L; 120 121 /** 122 * Lazily computed name of this class; always prefer calling getName(). 123 */ 124 private transient String name; 125 126 private Class() { 127 // Prevent this class to be instantiated, instance 128 // should be created by JVM only 129 } 130 131 /** 132 * Get the Signature attribute for this class. Returns null if not found. 133 */ 134 private String getSignatureAttribute() { 135 Object[] annotation = getSignatureAnnotation(); 136 137 if (annotation == null) { 138 return null; 139 } 140 141 return StringUtils.combineStrings(annotation); 142 } 143 144 /** 145 * Get the Signature annotation for this class. Returns null if not found. 146 */ 147 native private Object[] getSignatureAnnotation(); 148 149 /** 150 * Returns a {@code Class} object which represents the class with the 151 * specified name. The name should be the name of a class as described in 152 * the {@link Class class definition}; however, {@code Class}es representing 153 * primitive types can not be found using this method. 154 * <p> 155 * If the class has not been loaded so far, it is being loaded and linked 156 * first. This is done through either the class loader of the calling class 157 * or one of its parent class loaders. The class is also being initialized, 158 * which means that a possible static initializer block is executed. 159 * 160 * @param className 161 * the name of the non-primitive-type class to find. 162 * @return the named {@code Class} instance. 163 * @throws ClassNotFoundException 164 * if the requested class can not be found. 165 * @throws LinkageError 166 * if an error occurs during linkage 167 * @throws ExceptionInInitializerError 168 * if an exception occurs during static initialization of a 169 * class. 170 */ 171 public static Class<?> forName(String className) throws ClassNotFoundException { 172 return forName(className, true, VMStack.getCallingClassLoader()); 173 } 174 175 /** 176 * Returns a {@code Class} object which represents the class with the 177 * specified name. The name should be the name of a class as described in 178 * the {@link Class class definition}, however {@code Class}es representing 179 * primitive types can not be found using this method. Security rules will 180 * be obeyed. 181 * <p> 182 * If the class has not been loaded so far, it is being loaded and linked 183 * first. This is done through either the specified class loader or one of 184 * its parent class loaders. The caller can also request the class to be 185 * initialized, which means that a possible static initializer block is 186 * executed. 187 * 188 * @param className 189 * the name of the non-primitive-type class to find. 190 * @param initializeBoolean 191 * indicates whether the class should be initialized. 192 * @param classLoader 193 * the class loader to use to load the class. 194 * @return the named {@code Class} instance. 195 * @throws ClassNotFoundException 196 * if the requested class can not be found. 197 * @throws LinkageError 198 * if an error occurs during linkage 199 * @throws ExceptionInInitializerError 200 * if an exception occurs during static initialization of a 201 * class. 202 */ 203 public static Class<?> forName(String className, boolean initializeBoolean, 204 ClassLoader classLoader) throws ClassNotFoundException { 205 206 if (classLoader == null) { 207 classLoader = ClassLoader.getSystemClassLoader(); 208 } 209 // Catch an Exception thrown by the underlying native code. It wraps 210 // up everything inside a ClassNotFoundException, even if e.g. an 211 // Error occurred during initialization. This as a workaround for 212 // an ExceptionInInitilaizerError that's also wrapped. It is actually 213 // expected to be thrown. Maybe the same goes for other errors. 214 // Not wrapping up all the errors will break android though. 215 Class<?> result; 216 try { 217 result = classForName(className, initializeBoolean, 218 classLoader); 219 } catch (ClassNotFoundException e) { 220 Throwable cause = e.getCause(); 221 if (cause instanceof ExceptionInInitializerError) { 222 throw (ExceptionInInitializerError) cause; 223 } 224 throw e; 225 } 226 return result; 227 } 228 229 /* 230 * Returns a class by name without any security checks. 231 * 232 * @param className The name of the non-primitive type class to find 233 * @param initializeBoolean A boolean indicating whether the class should be 234 * initialized 235 * @param classLoader The class loader to use to load the class 236 * @return the named class. 237 * @throws ClassNotFoundException If the class could not be found 238 */ 239 static native Class<?> classForName(String className, boolean initializeBoolean, 240 ClassLoader classLoader) throws ClassNotFoundException; 241 242 /** 243 * Returns an array containing {@code Class} objects for all public classes 244 * and interfaces that are members of this class. This includes public 245 * members inherited from super classes and interfaces. If there are no such 246 * class members or if this object represents a primitive type then an array 247 * of length 0 is returned. 248 * 249 * @return the public class members of the class represented by this object. 250 */ 251 public Class<?>[] getClasses() { 252 return getFullListOfClasses(true); 253 } 254 255 @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) { 256 if (annotationType == null) { 257 throw new NullPointerException("annotationType == null"); 258 } 259 260 A annotation = getDeclaredAnnotation(annotationType); 261 if (annotation != null) { 262 return annotation; 263 } 264 265 if (annotationType.isAnnotationPresent(Inherited.class)) { 266 for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) { 267 annotation = sup.getDeclaredAnnotation(annotationType); 268 if (annotation != null) { 269 return annotation; 270 } 271 } 272 } 273 274 return null; 275 } 276 277 /** 278 * Returns all the annotations of this class. If there are no annotations 279 * then an empty array is returned. 280 * 281 * @return a copy of the array containing this class' annotations. 282 * @see #getDeclaredAnnotations() 283 */ 284 public Annotation[] getAnnotations() { 285 /* 286 * We need to get the annotations declared on this class, plus the 287 * annotations from superclasses that have the "@Inherited" annotation 288 * set. We create a temporary map to use while we accumulate the 289 * annotations and convert it to an array at the end. 290 * 291 * It's possible to have duplicates when annotations are inherited. 292 * We use a Map to filter those out. 293 * 294 * HashMap might be overkill here. 295 */ 296 HashMap<Class, Annotation> map = new HashMap<Class, Annotation>(); 297 Annotation[] declaredAnnotations = getDeclaredAnnotations(); 298 299 for (int i = declaredAnnotations.length-1; i >= 0; --i) { 300 map.put(declaredAnnotations[i].annotationType(), declaredAnnotations[i]); 301 } 302 for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) { 303 declaredAnnotations = sup.getDeclaredAnnotations(); 304 for (int i = declaredAnnotations.length-1; i >= 0; --i) { 305 Class<?> clazz = declaredAnnotations[i].annotationType(); 306 if (!map.containsKey(clazz) && clazz.isAnnotationPresent(Inherited.class)) { 307 map.put(clazz, declaredAnnotations[i]); 308 } 309 } 310 } 311 312 /* convert annotation values from HashMap to array */ 313 Collection<Annotation> coll = map.values(); 314 return coll.toArray(new Annotation[coll.size()]); 315 } 316 317 /** 318 * Returns the canonical name of this class. If this class does not have a 319 * canonical name as defined in the Java Language Specification, then the 320 * method returns {@code null}. 321 * 322 * @return this class' canonical name, or {@code null} if it does not have a 323 * canonical name. 324 */ 325 public String getCanonicalName() { 326 if (isLocalClass() || isAnonymousClass()) 327 return null; 328 329 if (isArray()) { 330 /* 331 * The canonical name of an array type depends on the (existence of) 332 * the component type's canonical name. 333 */ 334 String name = getComponentType().getCanonicalName(); 335 if (name != null) { 336 return name + "[]"; 337 } 338 } else if (isMemberClass()) { 339 /* 340 * The canonical name of an inner class depends on the (existence 341 * of) the declaring class' canonical name. 342 */ 343 String name = getDeclaringClass().getCanonicalName(); 344 if (name != null) { 345 return name + "." + getSimpleName(); 346 } 347 } else { 348 /* 349 * The canonical name of a top-level class or primitive type is 350 * equal to the fully qualified name. 351 */ 352 return getName(); 353 } 354 355 /* 356 * Other classes don't have a canonical name. 357 */ 358 return null; 359 } 360 361 /** 362 * Returns the class loader which was used to load the class represented by 363 * this {@code Class}. Implementations are free to return {@code null} for 364 * classes that were loaded by the bootstrap class loader. The Android 365 * reference implementation, though, returns a reference to an actual 366 * representation of the bootstrap class loader. 367 * 368 * @return the class loader for the represented class. 369 * @see ClassLoader 370 */ 371 public ClassLoader getClassLoader() { 372 if (this.isPrimitive()) { 373 return null; 374 } 375 376 ClassLoader loader = getClassLoaderImpl(); 377 if (loader == null) { 378 loader = BootClassLoader.getInstance(); 379 } 380 return loader; 381 } 382 383 /** 384 * This must be provided by the VM vendor, as it is used by other provided 385 * class implementations in this package. Outside of this class, it is used 386 * by SecurityManager.classLoaderDepth(), 387 * currentClassLoader() and currentLoadedClass(). Return the ClassLoader for 388 * this Class without doing any security checks. The bootstrap ClassLoader 389 * is returned, unlike getClassLoader() which returns null in place of the 390 * bootstrap ClassLoader. 391 * 392 * @return the ClassLoader 393 */ 394 ClassLoader getClassLoaderImpl() { 395 ClassLoader loader = getClassLoader(this); 396 return loader == null ? BootClassLoader.getInstance() : loader; 397 } 398 399 /* 400 * Returns the defining class loader for the given class. 401 * 402 * @param clazz the class the class loader of which we want 403 * @return the class loader 404 */ 405 private static native ClassLoader getClassLoader(Class<?> clazz); 406 407 /** 408 * Returns a {@code Class} object which represents the component type if 409 * this class represents an array type. Returns {@code null} if this class 410 * does not represent an array type. The component type of an array type is 411 * the type of the elements of the array. 412 * 413 * @return the component type of this class. 414 */ 415 public native Class<?> getComponentType(); 416 417 /** 418 * Returns a {@code Constructor} object which represents the public 419 * constructor matching the specified parameter types. 420 * 421 * @param parameterTypes 422 * the parameter types of the requested constructor. 423 * {@code (Class[]) null} is equivalent to the empty array. 424 * @return the constructor described by {@code parameterTypes}. 425 * @throws NoSuchMethodException 426 * if the constructor can not be found. 427 * @see #getDeclaredConstructor(Class[]) 428 */ 429 @SuppressWarnings("unchecked") 430 public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException { 431 return (Constructor) getConstructorOrMethod("<init>", false, true, parameterTypes); 432 } 433 434 /** 435 * Returns a constructor or method with the specified name. 436 * 437 * @param name the method name, or "<init>" to return a constructor. 438 * @param recursive true to search supertypes. 439 */ 440 private Member getConstructorOrMethod(String name, boolean recursive, 441 boolean publicOnly, Class<?>[] parameterTypes) throws NoSuchMethodException { 442 if (recursive && !publicOnly) { 443 throw new AssertionError(); // can't lookup non-public members recursively 444 } 445 if (name == null) { 446 throw new NullPointerException("name == null"); 447 } 448 if (parameterTypes == null) { 449 parameterTypes = EmptyArray.CLASS; 450 } 451 for (Class<?> c : parameterTypes) { 452 if (c == null) { 453 throw new NoSuchMethodException("parameter type is null"); 454 } 455 } 456 Member result = recursive 457 ? getPublicConstructorOrMethodRecursive(name, parameterTypes) 458 : Class.getDeclaredConstructorOrMethod(this, name, parameterTypes); 459 if (result == null || publicOnly && (result.getModifiers() & Modifier.PUBLIC) == 0) { 460 throw new NoSuchMethodException(name + " " + Arrays.toString(parameterTypes)); 461 } 462 return result; 463 } 464 465 private Member getPublicConstructorOrMethodRecursive(String name, Class<?>[] parameterTypes) { 466 // search superclasses 467 for (Class<?> c = this; c != null; c = c.getSuperclass()) { 468 Member result = Class.getDeclaredConstructorOrMethod(c, name, parameterTypes); 469 if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) { 470 return result; 471 } 472 } 473 474 // search implemented interfaces 475 for (Class<?> c = this; c != null; c = c.getSuperclass()) { 476 for (Class<?> ifc : c.getInterfaces()) { 477 Member result = ifc.getPublicConstructorOrMethodRecursive(name, parameterTypes); 478 if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) { 479 return result; 480 } 481 } 482 } 483 484 return null; 485 } 486 487 /** 488 * Returns an array containing {@code Constructor} objects for all public 489 * constructors for the class represented by this {@code Class}. If there 490 * are no public constructors or if this {@code Class} represents an array 491 * class, a primitive type or void then an empty array is returned. 492 * 493 * @return an array with the public constructors of the class represented by 494 * this {@code Class}. 495 * @see #getDeclaredConstructors() 496 */ 497 public Constructor<?>[] getConstructors() { 498 return getDeclaredConstructors(this, true); 499 } 500 501 /** 502 * Returns the annotations that are directly defined on the class 503 * represented by this {@code Class}. Annotations that are inherited are not 504 * included in the result. If there are no annotations at all, an empty 505 * array is returned. 506 * 507 * @return a copy of the array containing the annotations defined for the 508 * class that this {@code Class} represents. 509 * @see #getAnnotations() 510 */ 511 native public Annotation[] getDeclaredAnnotations(); 512 513 /** 514 * Returns the annotation if it exists. 515 */ 516 native private <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass); 517 518 /** 519 * Returns true if the annotation exists. 520 */ 521 native private boolean isDeclaredAnnotationPresent(Class<? extends Annotation> annotationClass); 522 523 /** 524 * Returns an array containing {@code Class} objects for all classes and 525 * interfaces that are declared as members of the class which this {@code 526 * Class} represents. If there are no classes or interfaces declared or if 527 * this class represents an array class, a primitive type or void, then an 528 * empty array is returned. 529 * 530 * @return an array with {@code Class} objects for all the classes and 531 * interfaces that are used in member declarations. 532 */ 533 public Class<?>[] getDeclaredClasses() { 534 return getDeclaredClasses(this, false); 535 } 536 537 /* 538 * Returns the list of member classes without performing any security checks 539 * first. This includes the member classes inherited from superclasses. If no 540 * member classes exist at all, an empty array is returned. 541 * 542 * @param publicOnly reflects whether we want only public members or all of them 543 * @return the list of classes 544 */ 545 private Class<?>[] getFullListOfClasses(boolean publicOnly) { 546 Class<?>[] result = getDeclaredClasses(this, publicOnly); 547 548 // Traverse all superclasses 549 Class<?> clazz = this.getSuperclass(); 550 while (clazz != null) { 551 Class<?>[] temp = getDeclaredClasses(clazz, publicOnly); 552 if (temp.length != 0) { 553 result = arraycopy(new Class[result.length + temp.length], result, temp); 554 } 555 556 clazz = clazz.getSuperclass(); 557 } 558 559 return result; 560 } 561 562 /* 563 * Returns the list of member classes of the given class. No security checks 564 * are performed. If no members exist, an empty array is returned. 565 * 566 * @param clazz the class the members of which we want 567 * @param publicOnly reflects whether we want only public member or all of them 568 * @return the class' class members 569 */ 570 private static native Class<?>[] getDeclaredClasses(Class<?> clazz, boolean publicOnly); 571 572 /** 573 * Returns a {@code Constructor} object which represents the constructor 574 * matching the specified parameter types that is declared by the class 575 * represented by this {@code Class}. 576 * 577 * @param parameterTypes 578 * the parameter types of the requested constructor. 579 * {@code (Class[]) null} is equivalent to the empty array. 580 * @return the constructor described by {@code parameterTypes}. 581 * @throws NoSuchMethodException 582 * if the requested constructor can not be found. 583 * @see #getConstructor(Class[]) 584 */ 585 @SuppressWarnings("unchecked") 586 public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 587 throws NoSuchMethodException { 588 return (Constructor) getConstructorOrMethod("<init>", false, false, parameterTypes); 589 } 590 591 /** 592 * Returns an array containing {@code Constructor} objects for all 593 * constructors declared in the class represented by this {@code Class}. If 594 * there are no constructors or if this {@code Class} represents an array 595 * class, a primitive type or void then an empty array is returned. 596 * 597 * @return an array with the constructors declared in the class represented 598 * by this {@code Class}. 599 * @see #getConstructors() 600 */ 601 public Constructor<?>[] getDeclaredConstructors() { 602 return getDeclaredConstructors(this, false); 603 } 604 605 /* 606 * Returns the list of constructors without performing any security checks 607 * first. If no constructors exist, an empty array is returned. 608 * 609 * @param clazz the class of interest 610 * @param publicOnly reflects whether we want only public constructors or all of them 611 * @return the list of constructors 612 */ 613 private static native <T> Constructor<T>[] getDeclaredConstructors( 614 Class<T> clazz, boolean publicOnly); 615 616 /** 617 * Returns a {@code Field} object for the field with the specified name 618 * which is declared in the class represented by this {@code Class}. 619 * 620 * @param name the name of the requested field. 621 * @return the requested field in the class represented by this class. 622 * @throws NoSuchFieldException if the requested field can not be found. 623 * @see #getField(String) 624 */ 625 public Field getDeclaredField(String name) throws NoSuchFieldException { 626 if (name == null) { 627 throw new NullPointerException("name == null"); 628 } 629 Field result = getDeclaredField(this, name); 630 if (result == null) { 631 throw new NoSuchFieldException(name); 632 } 633 return result; 634 } 635 636 /** 637 * Returns an array containing {@code Field} objects for all fields declared 638 * in the class represented by this {@code Class}. If there are no fields or 639 * if this {@code Class} represents an array class, a primitive type or void 640 * then an empty array is returned. 641 * 642 * @return an array with the fields declared in the class represented by 643 * this class. 644 * @see #getFields() 645 */ 646 public Field[] getDeclaredFields() { 647 return getDeclaredFields(this, false); 648 } 649 650 /* 651 * Returns the list of fields without performing any security checks 652 * first. If no fields exist at all, an empty array is returned. 653 * 654 * @param clazz the class of interest 655 * @param publicOnly reflects whether we want only public fields or all of them 656 * @return the list of fields 657 */ 658 static native Field[] getDeclaredFields(Class<?> clazz, boolean publicOnly); 659 660 /** 661 * Returns the field if it is defined by {@code clazz}; null otherwise. This 662 * may return a non-public member. 663 */ 664 static native Field getDeclaredField(Class<?> clazz, String name); 665 666 /** 667 * Returns a {@code Method} object which represents the method matching the 668 * specified name and parameter types that is declared by the class 669 * represented by this {@code Class}. 670 * 671 * @param name 672 * the requested method's name. 673 * @param parameterTypes 674 * the parameter types of the requested method. 675 * {@code (Class[]) null} is equivalent to the empty array. 676 * @return the method described by {@code name} and {@code parameterTypes}. 677 * @throws NoSuchMethodException 678 * if the requested constructor can not be found. 679 * @throws NullPointerException 680 * if {@code name} is {@code null}. 681 * @see #getMethod(String, Class[]) 682 */ 683 public Method getDeclaredMethod(String name, Class<?>... parameterTypes) 684 throws NoSuchMethodException { 685 Member member = getConstructorOrMethod(name, false, false, parameterTypes); 686 if (member instanceof Constructor) { 687 throw new NoSuchMethodException(name); 688 } 689 return (Method) member; 690 } 691 692 /** 693 * Returns an array containing {@code Method} objects for all methods 694 * declared in the class represented by this {@code Class}. If there are no 695 * methods or if this {@code Class} represents an array class, a primitive 696 * type or void then an empty array is returned. 697 * 698 * @return an array with the methods declared in the class represented by 699 * this {@code Class}. 700 * @see #getMethods() 701 */ 702 public Method[] getDeclaredMethods() { 703 return getDeclaredMethods(this, false); 704 } 705 706 /** 707 * Returns the list of methods without performing any security checks 708 * first. If no methods exist, an empty array is returned. 709 */ 710 static native Method[] getDeclaredMethods(Class<?> clazz, boolean publicOnly); 711 712 /** 713 * Returns the constructor or method if it is defined by {@code clazz}; null 714 * otherwise. This may return a non-public member. 715 * 716 * @param name the method name, or "<init>" to get a constructor. 717 */ 718 static native Member getDeclaredConstructorOrMethod(Class clazz, String name, Class[] args); 719 720 /** 721 * Returns the declaring {@code Class} of this {@code Class}. Returns 722 * {@code null} if the class is not a member of another class or if this 723 * {@code Class} represents an array class, a primitive type or void. 724 * 725 * @return the declaring {@code Class} or {@code null}. 726 */ 727 native public Class<?> getDeclaringClass(); 728 729 /** 730 * Returns the enclosing {@code Class} of this {@code Class}. If there is no 731 * enclosing class the method returns {@code null}. 732 * 733 * @return the enclosing {@code Class} or {@code null}. 734 */ 735 native public Class<?> getEnclosingClass(); 736 737 /** 738 * Gets the enclosing {@code Constructor} of this {@code Class}, if it is an 739 * anonymous or local/automatic class; otherwise {@code null}. 740 * 741 * @return the enclosing {@code Constructor} instance or {@code null}. 742 */ 743 native public Constructor<?> getEnclosingConstructor(); 744 745 /** 746 * Gets the enclosing {@code Method} of this {@code Class}, if it is an 747 * anonymous or local/automatic class; otherwise {@code null}. 748 * 749 * @return the enclosing {@code Method} instance or {@code null}. 750 */ 751 native public Method getEnclosingMethod(); 752 753 /** 754 * Gets the {@code enum} constants associated with this {@code Class}. 755 * Returns {@code null} if this {@code Class} does not represent an {@code 756 * enum} type. 757 * 758 * @return an array with the {@code enum} constants or {@code null}. 759 */ 760 @SuppressWarnings("unchecked") // we only cast after confirming that this class is an enum 761 public T[] getEnumConstants() { 762 if (!isEnum()) { 763 return null; 764 } 765 return (T[]) Enum.getSharedConstants((Class) this).clone(); 766 } 767 768 /** 769 * Returns a {@code Field} object which represents the public field with the 770 * specified name. This method first searches the class C represented by 771 * this {@code Class}, then the interfaces implemented by C and finally the 772 * superclasses of C. 773 * 774 * @param name 775 * the name of the requested field. 776 * @return the public field specified by {@code name}. 777 * @throws NoSuchFieldException 778 * if the field can not be found. 779 * @see #getDeclaredField(String) 780 */ 781 public Field getField(String name) throws NoSuchFieldException { 782 if (name == null) { 783 throw new NullPointerException("name == null"); 784 } 785 Field result = getPublicFieldRecursive(name); 786 if (result == null) { 787 throw new NoSuchFieldException(name); 788 } 789 return result; 790 } 791 792 private Field getPublicFieldRecursive(String name) { 793 // search superclasses 794 for (Class<?> c = this; c != null; c = c.getSuperclass()) { 795 Field result = Class.getDeclaredField(c, name); 796 if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) { 797 return result; 798 } 799 } 800 801 // search implemented interfaces 802 for (Class<?> c = this; c != null; c = c.getSuperclass()) { 803 for (Class<?> ifc : c.getInterfaces()) { 804 Field result = ifc.getPublicFieldRecursive(name); 805 if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) { 806 return result; 807 } 808 } 809 } 810 811 return null; 812 } 813 814 /** 815 * Returns an array containing {@code Field} objects for all public fields 816 * for the class C represented by this {@code Class}. Fields may be declared 817 * in C, the interfaces it implements or in the superclasses of C. The 818 * elements in the returned array are in no particular order. 819 * 820 * <p>If there are no public fields or if this class represents an array class, 821 * a primitive type or {@code void} then an empty array is returned. 822 * 823 * @return an array with the public fields of the class represented by this 824 * {@code Class}. 825 * @see #getDeclaredFields() 826 */ 827 public Field[] getFields() { 828 List<Field> fields = new ArrayList<Field>(); 829 getPublicFieldsRecursive(fields); 830 831 /* 832 * The result may include duplicates when clazz implements an interface 833 * through multiple paths. Remove those duplicates. 834 */ 835 CollectionUtils.removeDuplicates(fields, Field.ORDER_BY_NAME_AND_DECLARING_CLASS); 836 return fields.toArray(new Field[fields.size()]); 837 } 838 839 /** 840 * Populates {@code result} with public fields defined by this class, its 841 * superclasses, and all implemented interfaces. 842 */ 843 private void getPublicFieldsRecursive(List<Field> result) { 844 // search superclasses 845 for (Class<?> c = this; c != null; c = c.getSuperclass()) { 846 for (Field field : Class.getDeclaredFields(c, true)) { 847 result.add(field); 848 } 849 } 850 851 // search implemented interfaces 852 for (Class<?> c = this; c != null; c = c.getSuperclass()) { 853 for (Class<?> ifc : c.getInterfaces()) { 854 ifc.getPublicFieldsRecursive(result); 855 } 856 } 857 } 858 859 /** 860 * Gets the {@link Type}s of the interfaces that this {@code Class} directly 861 * implements. If the {@code Class} represents a primitive type or {@code 862 * void} then an empty array is returned. 863 * 864 * @return an array of {@link Type} instances directly implemented by the 865 * class represented by this {@code class}. 866 */ 867 public Type[] getGenericInterfaces() { 868 GenericSignatureParser parser = new GenericSignatureParser(getClassLoader()); 869 parser.parseForClass(this, getSignatureAttribute()); 870 return Types.getClonedTypeArray(parser.interfaceTypes); 871 } 872 873 /** 874 * Gets the {@code Type} that represents the superclass of this {@code 875 * class}. 876 * 877 * @return an instance of {@code Type} representing the superclass. 878 */ 879 public Type getGenericSuperclass() { 880 GenericSignatureParser parser = new GenericSignatureParser(getClassLoader()); 881 parser.parseForClass(this, getSignatureAttribute()); 882 return Types.getType(parser.superclassType); 883 } 884 885 /** 886 * Returns an array of {@code Class} objects that match the interfaces 887 * specified in the {@code implements} declaration of the class represented 888 * by this {@code Class}. The order of the elements in the array is 889 * identical to the order in the original class declaration. If the class 890 * does not implement any interfaces, an empty array is returned. 891 * 892 * @return an array with the interfaces of the class represented by this 893 * class. 894 */ 895 public native Class<?>[] getInterfaces(); 896 897 /** 898 * Returns a {@code Method} object which represents the public method with 899 * the specified name and parameter types. This method first searches the 900 * class C represented by this {@code Class}, then the superclasses of C and 901 * finally the interfaces implemented by C and finally the superclasses of C 902 * for a method with matching name. 903 * 904 * @param name 905 * the requested method's name. 906 * @param parameterTypes 907 * the parameter types of the requested method. 908 * {@code (Class[]) null} is equivalent to the empty array. 909 * @return the public field specified by {@code name}. 910 * @throws NoSuchMethodException 911 * if the method can not be found. 912 * @see #getDeclaredMethod(String, Class[]) 913 */ 914 public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException { 915 Member member = getConstructorOrMethod(name, true, true, parameterTypes); 916 if (member instanceof Constructor) { 917 throw new NoSuchMethodException(name); 918 } 919 return (Method) member; 920 } 921 922 /** 923 * Returns an array containing {@code Method} objects for all public methods 924 * for the class C represented by this {@code Class}. Methods may be 925 * declared in C, the interfaces it implements or in the superclasses of C. 926 * The elements in the returned array are in no particular order. 927 * <p> 928 * If there are no public methods or if this {@code Class} represents a 929 * primitive type or {@code void} then an empty array is returned. 930 * </p> 931 * 932 * @return an array with the methods of the class represented by this 933 * {@code Class}. 934 * @see #getDeclaredMethods() 935 */ 936 public Method[] getMethods() { 937 List<Method> methods = new ArrayList<Method>(); 938 getPublicMethodsRecursive(methods); 939 940 /* 941 * Remove methods defined by multiple types, preferring to keep methods 942 * declared by derived types. 943 */ 944 CollectionUtils.removeDuplicates(methods, Method.ORDER_BY_SIGNATURE); 945 return methods.toArray(new Method[methods.size()]); 946 } 947 948 /** 949 * Populates {@code result} with public methods defined by {@code clazz}, its 950 * superclasses, and all implemented interfaces, including overridden methods. 951 */ 952 private void getPublicMethodsRecursive(List<Method> result) { 953 // search superclasses 954 for (Class<?> c = this; c != null; c = c.getSuperclass()) { 955 for (Method method : Class.getDeclaredMethods(c, true)) { 956 result.add(method); 957 } 958 } 959 960 // search implemented interfaces 961 for (Class<?> c = this; c != null; c = c.getSuperclass()) { 962 for (Class<?> ifc : c.getInterfaces()) { 963 ifc.getPublicMethodsRecursive(result); 964 } 965 } 966 } 967 968 /** 969 * Returns an integer that represents the modifiers of the class represented 970 * by this {@code Class}. The returned value is a combination of bits 971 * defined by constants in the {@link Modifier} class. 972 * 973 * @return the modifiers of the class represented by this {@code Class}. 974 */ 975 public int getModifiers() { 976 return getModifiers(this, false); 977 } 978 979 /* 980 * Return the modifiers for the given class. 981 * 982 * @param clazz the class of interest 983 * @ignoreInnerClassesAttrib determines whether we look for and use the 984 * flags from an "inner class" attribute 985 */ 986 private static native int getModifiers(Class<?> clazz, boolean ignoreInnerClassesAttrib); 987 988 /** 989 * Returns the name of the class represented by this {@code Class}. For a 990 * description of the format which is used, see the class definition of 991 * {@link Class}. 992 * 993 * @return the name of the class represented by this {@code Class}. 994 */ 995 public String getName() { 996 String result = name; 997 return (result == null) ? (name = getNameNative()) : result; 998 } 999 1000 private native String getNameNative(); 1001 1002 /** 1003 * Returns the simple name of the class represented by this {@code Class} as 1004 * defined in the source code. If there is no name (that is, the class is 1005 * anonymous) then an empty string is returned. If the receiver is an array 1006 * then the name of the underlying type with square braces appended (for 1007 * example {@code "Integer[]"}) is returned. 1008 * 1009 * @return the simple name of the class represented by this {@code Class}. 1010 */ 1011 public String getSimpleName() { 1012 if (isArray()) { 1013 return getComponentType().getSimpleName() + "[]"; 1014 } 1015 1016 String name = getName(); 1017 1018 if (isAnonymousClass()) { 1019 return ""; 1020 } 1021 1022 if (isMemberClass() || isLocalClass()) { 1023 return getInnerClassName(); 1024 } 1025 1026 int dot = name.lastIndexOf('.'); 1027 if (dot != -1) { 1028 return name.substring(dot + 1); 1029 } 1030 1031 return name; 1032 } 1033 1034 /* 1035 * Returns the simple name of a member or local class, or null otherwise. 1036 * 1037 * @return The name. 1038 */ 1039 private native String getInnerClassName(); 1040 1041 /** 1042 * Returns null. 1043 */ 1044 public ProtectionDomain getProtectionDomain() { 1045 return null; 1046 } 1047 1048 /** 1049 * Returns the URL of the resource specified by {@code resName}. The mapping 1050 * between the resource name and the URL is managed by the class' class 1051 * loader. 1052 * 1053 * @param resName 1054 * the name of the resource. 1055 * @return the requested resource's {@code URL} object or {@code null} if 1056 * the resource can not be found. 1057 * @see ClassLoader 1058 */ 1059 public URL getResource(String resName) { 1060 // Get absolute resource name, but without the leading slash 1061 if (resName.startsWith("/")) { 1062 resName = resName.substring(1); 1063 } else { 1064 String pkg = getName(); 1065 int dot = pkg.lastIndexOf('.'); 1066 if (dot != -1) { 1067 pkg = pkg.substring(0, dot).replace('.', '/'); 1068 } else { 1069 pkg = ""; 1070 } 1071 1072 resName = pkg + "/" + resName; 1073 } 1074 1075 // Delegate to proper class loader 1076 ClassLoader loader = getClassLoader(); 1077 if (loader != null) { 1078 return loader.getResource(resName); 1079 } else { 1080 return ClassLoader.getSystemResource(resName); 1081 } 1082 } 1083 1084 /** 1085 * Returns a read-only stream for the contents of the resource specified by 1086 * {@code resName}. The mapping between the resource name and the stream is 1087 * managed by the class' class loader. 1088 * 1089 * @param resName 1090 * the name of the resource. 1091 * @return a stream for the requested resource or {@code null} if no 1092 * resource with the specified name can be found. 1093 * @see ClassLoader 1094 */ 1095 public InputStream getResourceAsStream(String resName) { 1096 // Get absolute resource name, but without the leading slash 1097 if (resName.startsWith("/")) { 1098 resName = resName.substring(1); 1099 } else { 1100 String pkg = getName(); 1101 int dot = pkg.lastIndexOf('.'); 1102 if (dot != -1) { 1103 pkg = pkg.substring(0, dot).replace('.', '/'); 1104 } else { 1105 pkg = ""; 1106 } 1107 1108 resName = pkg + "/" + resName; 1109 } 1110 1111 // Delegate to proper class loader 1112 ClassLoader loader = getClassLoader(); 1113 if (loader != null) { 1114 return loader.getResourceAsStream(resName); 1115 } else { 1116 return ClassLoader.getSystemResourceAsStream(resName); 1117 } 1118 } 1119 1120 /** 1121 * Returns null. (On Android, a {@code ClassLoader} can load classes from multiple dex files. 1122 * All classes from any given dex file will have the same signers, but different dex 1123 * files may have different signers. This does not fit well with the original 1124 * {@code ClassLoader}-based model of {@code getSigners}.) 1125 * 1126 * @return null. 1127 */ 1128 public Object[] getSigners() { 1129 // See http://code.google.com/p/android/issues/detail?id=1766. 1130 return null; 1131 } 1132 1133 /** 1134 * Returns the {@code Class} object which represents the superclass of the 1135 * class represented by this {@code Class}. If this {@code Class} represents 1136 * the {@code Object} class, a primitive type, an interface or void then the 1137 * method returns {@code null}. If this {@code Class} represents an array 1138 * class then the {@code Object} class is returned. 1139 * 1140 * @return the superclass of the class represented by this {@code Class}. 1141 */ 1142 public native Class<? super T> getSuperclass(); 1143 1144 /** 1145 * Returns an array containing {@code TypeVariable} objects for type 1146 * variables declared by the generic class represented by this {@code 1147 * Class}. Returns an empty array if the class is not generic. 1148 * 1149 * @return an array with the type variables of the class represented by this 1150 * class. 1151 */ 1152 @SuppressWarnings("unchecked") 1153 public synchronized TypeVariable<Class<T>>[] getTypeParameters() { 1154 GenericSignatureParser parser = new GenericSignatureParser(getClassLoader()); 1155 parser.parseForClass(this, getSignatureAttribute()); 1156 return parser.formalTypeParameters.clone(); 1157 } 1158 1159 /** 1160 * Indicates whether this {@code Class} represents an annotation class. 1161 * 1162 * @return {@code true} if this {@code Class} represents an annotation 1163 * class; {@code false} otherwise. 1164 */ 1165 public boolean isAnnotation() { 1166 final int ACC_ANNOTATION = 0x2000; // not public in reflect.Modifiers 1167 int mod = getModifiers(this, true); 1168 return (mod & ACC_ANNOTATION) != 0; 1169 } 1170 1171 @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) { 1172 if (annotationType == null) { 1173 throw new NullPointerException("annotationType == null"); 1174 } 1175 1176 if (isDeclaredAnnotationPresent(annotationType)) { 1177 return true; 1178 } 1179 1180 if (annotationType.isDeclaredAnnotationPresent(Inherited.class)) { 1181 for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) { 1182 if (sup.isDeclaredAnnotationPresent(annotationType)) { 1183 return true; 1184 } 1185 } 1186 } 1187 1188 return false; 1189 } 1190 1191 /** 1192 * Indicates whether the class represented by this {@code Class} is 1193 * anonymously declared. 1194 * 1195 * @return {@code true} if the class represented by this {@code Class} is 1196 * anonymous; {@code false} otherwise. 1197 */ 1198 native public boolean isAnonymousClass(); 1199 1200 /** 1201 * Indicates whether the class represented by this {@code Class} is an array 1202 * class. 1203 * 1204 * @return {@code true} if the class represented by this {@code Class} is an 1205 * array class; {@code false} otherwise. 1206 */ 1207 public boolean isArray() { 1208 return getComponentType() != null; 1209 } 1210 1211 /** 1212 * Indicates whether the specified class type can be converted to the class 1213 * represented by this {@code Class}. Conversion may be done via an identity 1214 * conversion or a widening reference conversion (if either the receiver or 1215 * the argument represent primitive types, only the identity conversion 1216 * applies). 1217 * 1218 * @param cls 1219 * the class to check. 1220 * @return {@code true} if {@code cls} can be converted to the class 1221 * represented by this {@code Class}; {@code false} otherwise. 1222 * @throws NullPointerException 1223 * if {@code cls} is {@code null}. 1224 */ 1225 public native boolean isAssignableFrom(Class<?> cls); 1226 1227 /** 1228 * Indicates whether the class represented by this {@code Class} is an 1229 * {@code enum}. 1230 * 1231 * @return {@code true} if the class represented by this {@code Class} is an 1232 * {@code enum}; {@code false} otherwise. 1233 */ 1234 public boolean isEnum() { 1235 return ((getModifiers() & 0x4000) != 0) && (getSuperclass() == Enum.class); 1236 } 1237 1238 /** 1239 * Indicates whether the specified object can be cast to the class 1240 * represented by this {@code Class}. This is the runtime version of the 1241 * {@code instanceof} operator. 1242 * 1243 * @param object 1244 * the object to check. 1245 * @return {@code true} if {@code object} can be cast to the type 1246 * represented by this {@code Class}; {@code false} if {@code 1247 * object} is {@code null} or cannot be cast. 1248 */ 1249 public native boolean isInstance(Object object); 1250 1251 /** 1252 * Indicates whether this {@code Class} represents an interface. 1253 * 1254 * @return {@code true} if this {@code Class} represents an interface; 1255 * {@code false} otherwise. 1256 */ 1257 public native boolean isInterface(); 1258 1259 /** 1260 * Indicates whether the class represented by this {@code Class} is defined 1261 * locally. 1262 * 1263 * @return {@code true} if the class represented by this {@code Class} is 1264 * defined locally; {@code false} otherwise. 1265 */ 1266 public boolean isLocalClass() { 1267 boolean enclosed = (getEnclosingMethod() != null || 1268 getEnclosingConstructor() != null); 1269 return enclosed && !isAnonymousClass(); 1270 } 1271 1272 /** 1273 * Indicates whether the class represented by this {@code Class} is a member 1274 * class. 1275 * 1276 * @return {@code true} if the class represented by this {@code Class} is a 1277 * member class; {@code false} otherwise. 1278 */ 1279 public boolean isMemberClass() { 1280 return getDeclaringClass() != null; 1281 } 1282 1283 /** 1284 * Indicates whether this {@code Class} represents a primitive type. 1285 * 1286 * @return {@code true} if this {@code Class} represents a primitive type; 1287 * {@code false} otherwise. 1288 */ 1289 public native boolean isPrimitive(); 1290 1291 /** 1292 * Indicates whether this {@code Class} represents a synthetic type. 1293 * 1294 * @return {@code true} if this {@code Class} represents a synthetic type; 1295 * {@code false} otherwise. 1296 */ 1297 public boolean isSynthetic() { 1298 final int ACC_SYNTHETIC = 0x1000; // not public in reflect.Modifiers 1299 int mod = getModifiers(this, true); 1300 return (mod & ACC_SYNTHETIC) != 0; 1301 } 1302 1303 /** 1304 * Returns a new instance of the class represented by this {@code Class}, 1305 * created by invoking the default (that is, zero-argument) constructor. If 1306 * there is no such constructor, or if the creation fails (either because of 1307 * a lack of available memory or because an exception is thrown by the 1308 * constructor), an {@code InstantiationException} is thrown. If the default 1309 * constructor exists but is not accessible from the context where this 1310 * method is invoked, an {@code IllegalAccessException} is thrown. 1311 * 1312 * @return a new instance of the class represented by this {@code Class}. 1313 * @throws IllegalAccessException 1314 * if the default constructor is not visible. 1315 * @throws InstantiationException 1316 * if the instance can not be created. 1317 */ 1318 public T newInstance() throws InstantiationException, IllegalAccessException { 1319 return newInstanceImpl(); 1320 } 1321 1322 private native T newInstanceImpl() throws IllegalAccessException, InstantiationException; 1323 1324 @Override 1325 public String toString() { 1326 if (isPrimitive()) { 1327 return getSimpleName(); 1328 } else { 1329 return (isInterface() ? "interface " : "class ") + getName(); 1330 } 1331 } 1332 1333 /** 1334 * Returns the {@code Package} of which the class represented by this 1335 * {@code Class} is a member. Returns {@code null} if no {@code Package} 1336 * object was created by the class loader of the class. 1337 * 1338 * @return Package the {@code Package} of which this {@code Class} is a 1339 * member or {@code null}. 1340 */ 1341 public Package getPackage() { 1342 // TODO This might be a hack, but the VM doesn't have the necessary info. 1343 ClassLoader loader = getClassLoader(); 1344 if (loader != null) { 1345 String name = getName(); 1346 int dot = name.lastIndexOf('.'); 1347 return (dot != -1 ? loader.getPackage(name.substring(0, dot)) : null); 1348 } 1349 return null; 1350 } 1351 1352 /** 1353 * Returns the assertion status for the class represented by this {@code 1354 * Class}. Assertion is enabled / disabled based on the class loader, 1355 * package or class default at runtime. 1356 * 1357 * @return the assertion status for the class represented by this {@code 1358 * Class}. 1359 */ 1360 public native boolean desiredAssertionStatus(); 1361 1362 /** 1363 * Casts this {@code Class} to represent a subclass of the specified class. 1364 * If successful, this {@code Class} is returned; otherwise a {@code 1365 * ClassCastException} is thrown. 1366 * 1367 * @param clazz 1368 * the required type. 1369 * @return this {@code Class} cast as a subclass of the given type. 1370 * @throws ClassCastException 1371 * if this {@code Class} cannot be cast to the specified type. 1372 */ 1373 @SuppressWarnings("unchecked") 1374 public <U> Class<? extends U> asSubclass(Class<U> clazz) { 1375 if (clazz.isAssignableFrom(this)) { 1376 return (Class<? extends U>)this; 1377 } 1378 String actualClassName = this.getName(); 1379 String desiredClassName = clazz.getName(); 1380 throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName); 1381 } 1382 1383 /** 1384 * Casts the specified object to the type represented by this {@code Class}. 1385 * If the object is {@code null} then the result is also {@code null}. 1386 * 1387 * @param obj 1388 * the object to cast. 1389 * @return the object that has been cast. 1390 * @throws ClassCastException 1391 * if the object cannot be cast to the specified type. 1392 */ 1393 @SuppressWarnings("unchecked") 1394 public T cast(Object obj) { 1395 if (obj == null) { 1396 return null; 1397 } else if (this.isInstance(obj)) { 1398 return (T)obj; 1399 } 1400 String actualClassName = obj.getClass().getName(); 1401 String desiredClassName = this.getName(); 1402 throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName); 1403 } 1404 1405 /** 1406 * Copies two arrays into one. Assumes that the destination array is large 1407 * enough. 1408 * 1409 * @param result the destination array 1410 * @param head the first source array 1411 * @param tail the second source array 1412 * @return the destination array, that is, result 1413 */ 1414 private static <T extends Object> T[] arraycopy(T[] result, T[] head, T[] tail) { 1415 System.arraycopy(head, 0, result, 0, head.length); 1416 System.arraycopy(tail, 0, result, head.length, tail.length); 1417 return result; 1418 } 1419 }
Constructorandroid
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /* 18 * Copyright (C) 2008 The Android Open Source Project 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33 package java.lang.reflect; 34 35 import java.lang.annotation.Annotation; 36 import libcore.util.EmptyArray; 37 import org.apache.harmony.kernel.vm.StringUtils; 38 import org.apache.harmony.luni.lang.reflect.GenericSignatureParser; 39 import org.apache.harmony.luni.lang.reflect.ListOfTypes; 40 import org.apache.harmony.luni.lang.reflect.Types; 41 42 /** 43 * This class represents a constructor. Information about the constructor can be 44 * accessed, and the constructor can be invoked dynamically. 45 * 46 * @param <T> the class that declares this constructor 47 */ 48 public final class Constructor<T> extends AccessibleObject implements GenericDeclaration, 49 Member { 50 51 Class<T> declaringClass; 52 53 Class<?>[] parameterTypes; 54 55 Class<?>[] exceptionTypes; 56 57 ListOfTypes genericExceptionTypes; 58 ListOfTypes genericParameterTypes; 59 TypeVariable<Constructor<T>>[] formalTypeParameters; 60 private volatile boolean genericTypesAreInitialized = false; 61 62 private synchronized void initGenericTypes() { 63 if (!genericTypesAreInitialized) { 64 String signatureAttribute = getSignatureAttribute(); 65 GenericSignatureParser parser = new GenericSignatureParser( 66 declaringClass.getClassLoader()); 67 parser.parseForConstructor(this, signatureAttribute, exceptionTypes); 68 formalTypeParameters = parser.formalTypeParameters; 69 genericParameterTypes = parser.parameterTypes; 70 genericExceptionTypes = parser.exceptionTypes; 71 genericTypesAreInitialized = true; 72 } 73 } 74 75 int slot; 76 77 /** 78 * Prevent this class from being instantiated. 79 */ 80 private Constructor(){ 81 //do nothing 82 } 83 84 /** 85 * Creates an instance of the class. Only called from native code, thus 86 * private. 87 * 88 * @param declaringClass 89 * the class this constructor object belongs to 90 * @param ptypes 91 * the parameter types of the constructor 92 * @param extypes 93 * the exception types of the constructor 94 * @param slot 95 * the slot of the constructor inside the VM class structure 96 */ 97 private Constructor (Class<T> declaringClass, Class<?>[] ptypes, Class<?>[] extypes, int slot){ 98 this.declaringClass = declaringClass; 99 this.parameterTypes = ptypes; 100 this.exceptionTypes = extypes; // may be null 101 this.slot = slot; 102 } 103 104 @Override /*package*/ String getSignatureAttribute() { 105 Object[] annotation = Method.getSignatureAnnotation(declaringClass, slot); 106 107 if (annotation == null) { 108 return null; 109 } 110 111 return StringUtils.combineStrings(annotation); 112 } 113 114 public TypeVariable<Constructor<T>>[] getTypeParameters() { 115 initGenericTypes(); 116 return formalTypeParameters.clone(); 117 } 118 119 /** 120 * Returns the string representation of the constructor's declaration, 121 * including the type parameters. 122 * 123 * @return the string representation of the constructor's declaration 124 */ 125 public String toGenericString() { 126 StringBuilder sb = new StringBuilder(80); 127 initGenericTypes(); 128 // append modifiers if any 129 int modifier = getModifiers(); 130 if (modifier != 0) { 131 sb.append(Modifier.toString(modifier & ~Modifier.VARARGS)).append(' '); 132 } 133 // append type parameters 134 if (formalTypeParameters != null && formalTypeParameters.length > 0) { 135 sb.append('<'); 136 for (int i = 0; i < formalTypeParameters.length; i++) { 137 appendGenericType(sb, formalTypeParameters[i]); 138 if (i < formalTypeParameters.length - 1) { 139 sb.append(","); 140 } 141 } 142 sb.append("> "); 143 } 144 // append constructor name 145 appendArrayType(sb, getDeclaringClass()); 146 // append parameters 147 sb.append('('); 148 appendArrayGenericType(sb, 149 Types.getClonedTypeArray(genericParameterTypes)); 150 sb.append(')'); 151 // append exceptions if any 152 Type[] genericExceptionTypeArray = 153 Types.getClonedTypeArray(genericExceptionTypes); 154 if (genericExceptionTypeArray.length > 0) { 155 sb.append(" throws "); 156 appendArrayGenericType(sb, genericExceptionTypeArray); 157 } 158 return sb.toString(); 159 } 160 161 /** 162 * Returns the generic parameter types as an array of {@code Type} 163 * instances, in declaration order. If this constructor has no generic 164 * parameters, an empty array is returned. 165 * 166 * @return the parameter types 167 * 168 * @throws GenericSignatureFormatError 169 * if the generic constructor signature is invalid 170 * @throws TypeNotPresentException 171 * if any parameter type points to a missing type 172 * @throws MalformedParameterizedTypeException 173 * if any parameter type points to a type that cannot be 174 * instantiated for some reason 175 */ 176 public Type[] getGenericParameterTypes() { 177 initGenericTypes(); 178 return Types.getClonedTypeArray(genericParameterTypes); 179 } 180 181 /** 182 * Returns the exception types as an array of {@code Type} instances. If 183 * this constructor has no declared exceptions, an empty array will be 184 * returned. 185 * 186 * @return an array of generic exception types 187 * 188 * @throws GenericSignatureFormatError 189 * if the generic constructor signature is invalid 190 * @throws TypeNotPresentException 191 * if any exception type points to a missing type 192 * @throws MalformedParameterizedTypeException 193 * if any exception type points to a type that cannot be 194 * instantiated for some reason 195 */ 196 public Type[] getGenericExceptionTypes() { 197 initGenericTypes(); 198 return Types.getClonedTypeArray(genericExceptionTypes); 199 } 200 201 @Override 202 public Annotation[] getDeclaredAnnotations() { 203 return Method.getDeclaredAnnotations(declaringClass, slot); 204 } 205 206 @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) { 207 if (annotationType == null) { 208 throw new NullPointerException("annotationType == null"); 209 } 210 return Method.getAnnotation(declaringClass, slot, annotationType); 211 } 212 213 @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) { 214 if (annotationType == null) { 215 throw new NullPointerException("annotationType == null"); 216 } 217 return Method.isAnnotationPresent(declaringClass, slot, annotationType); 218 } 219 220 /** 221 * Returns an array of arrays that represent the annotations of the formal 222 * parameters of this constructor. If there are no parameters on this 223 * constructor, then an empty array is returned. If there are no annotations 224 * set, then an array of empty arrays is returned. 225 * 226 * @return an array of arrays of {@code Annotation} instances 227 */ 228 public Annotation[][] getParameterAnnotations() { 229 Annotation[][] parameterAnnotations 230 = Method.getParameterAnnotations(declaringClass, slot); 231 if (parameterAnnotations.length == 0) { 232 return Method.noAnnotations(parameterTypes.length); 233 } 234 return parameterAnnotations; 235 } 236 237 /** 238 * Indicates whether or not this constructor takes a variable number of 239 * arguments. 240 * 241 * @return {@code true} if a vararg is declare, otherwise 242 * {@code false} 243 */ 244 public boolean isVarArgs() { 245 int mods = Method.getMethodModifiers(declaringClass, slot); 246 return (mods & Modifier.VARARGS) != 0; 247 } 248 249 /** 250 * Indicates whether or not this constructor is synthetic (artificially 251 * introduced by the compiler). 252 * 253 * @return {@code true} if this constructor is synthetic, {@code false} 254 * otherwise 255 */ 256 public boolean isSynthetic() { 257 int mods = Method.getMethodModifiers(declaringClass, slot); 258 return (mods & Modifier.SYNTHETIC) != 0; 259 } 260 261 /** 262 * Indicates whether or not the specified {@code object} is equal to this 263 * constructor. To be equal, the specified object must be an instance 264 * of {@code Constructor} with the same declaring class and parameter types 265 * as this constructor. 266 * 267 * @param object 268 * the object to compare 269 * 270 * @return {@code true} if the specified object is equal to this 271 * constructor, {@code false} otherwise 272 * 273 * @see #hashCode 274 */ 275 @Override 276 public boolean equals(Object object) { 277 return object instanceof Constructor && toString().equals(object.toString()); 278 } 279 280 /** 281 * Returns the class that declares this constructor. 282 * 283 * @return the declaring class 284 */ 285 public Class<T> getDeclaringClass() { 286 return declaringClass; 287 } 288 289 /** 290 * Returns the exception types as an array of {@code Class} instances. If 291 * this constructor has no declared exceptions, an empty array will be 292 * returned. 293 * 294 * @return the declared exception classes 295 */ 296 public Class<?>[] getExceptionTypes() { 297 if (exceptionTypes == null) { 298 return EmptyArray.CLASS; 299 } 300 return exceptionTypes.clone(); 301 } 302 303 /** 304 * Returns the modifiers for this constructor. The {@link Modifier} class 305 * should be used to decode the result. 306 * 307 * @return the modifiers for this constructor 308 * 309 * @see Modifier 310 */ 311 public int getModifiers() { 312 return Method.getMethodModifiers(declaringClass, slot); 313 } 314 315 /** 316 * Returns the name of this constructor. 317 * 318 * @return the name of this constructor 319 */ 320 public String getName() { 321 return declaringClass.getName(); 322 } 323 324 /** 325 * Returns an array of the {@code Class} objects associated with the 326 * parameter types of this constructor. If the constructor was declared with 327 * no parameters, an empty array will be returned. 328 * 329 * @return the parameter types 330 */ 331 public Class<?>[] getParameterTypes() { 332 return parameterTypes.clone(); 333 } 334 335 /** 336 * Returns the constructor's signature in non-printable form. This is called 337 * (only) from IO native code and needed for deriving the serialVersionUID 338 * of the class 339 * 340 * @return the constructor's signature 341 */ 342 @SuppressWarnings("unused") 343 private String getSignature() { 344 StringBuilder result = new StringBuilder(); 345 346 result.append('('); 347 for (int i = 0; i < parameterTypes.length; i++) { 348 result.append(getSignature(parameterTypes[i])); 349 } 350 result.append(")V"); 351 352 return result.toString(); 353 } 354 355 /** 356 * Returns an integer hash code for this constructor. Constructors which are 357 * equal return the same value for this method. The hash code for a 358 * Constructor is the hash code of the name of the declaring class. 359 * 360 * @return the hash code 361 * 362 * @see #equals 363 */ 364 @Override 365 public int hashCode() { 366 return declaringClass.getName().hashCode(); 367 } 368 369 /** 370 * Returns a new instance of the declaring class, initialized by dynamically 371 * invoking the constructor represented by this {@code Constructor} object. 372 * This reproduces the effect of {@code new declaringClass(arg1, arg2, ... , 373 * argN)} This method performs the following: 374 * <ul> 375 * <li>A new instance of the declaring class is created. If the declaring 376 * class cannot be instantiated (i.e. abstract class, an interface, an array 377 * type, or a primitive type) then an InstantiationException is thrown.</li> 378 * <li>If this Constructor object is enforcing access control (see 379 * {@link AccessibleObject}) and this constructor is not accessible from the 380 * current context, an IllegalAccessException is thrown.</li> 381 * <li>If the number of arguments passed and the number of parameters do not 382 * match, an IllegalArgumentException is thrown.</li> 383 * <li>For each argument passed: 384 * <ul> 385 * <li>If the corresponding parameter type is a primitive type, the argument 386 * is unboxed. If the unboxing fails, an IllegalArgumentException is 387 * thrown.</li> 388 * <li>If the resulting argument cannot be converted to the parameter type 389 * via a widening conversion, an IllegalArgumentException is thrown.</li> 390 * </ul> 391 * <li>The constructor represented by this {@code Constructor} object is 392 * then invoked. If an exception is thrown during the invocation, it is 393 * caught and wrapped in an InvocationTargetException. This exception is 394 * then thrown. If the invocation completes normally, the newly initialized 395 * object is returned. 396 * </ul> 397 * 398 * @param args 399 * the arguments to the constructor 400 * 401 * @return the new, initialized, object 402 * 403 * @exception InstantiationException 404 * if the class cannot be instantiated 405 * @exception IllegalAccessException 406 * if this constructor is not accessible 407 * @exception IllegalArgumentException 408 * if an incorrect number of arguments are passed, or an 409 * argument could not be converted by a widening conversion 410 * @exception InvocationTargetException 411 * if an exception was thrown by the invoked constructor 412 * 413 * @see AccessibleObject 414 */ 415 public T newInstance(Object... args) throws InstantiationException, IllegalAccessException, 416 IllegalArgumentException, InvocationTargetException { 417 return constructNative (args, declaringClass, parameterTypes, slot, flag); 418 } 419 420 private native T constructNative(Object[] args, Class<T> declaringClass, 421 Class<?>[] parameterTypes, int slot, 422 boolean noAccessCheck) throws InstantiationException, IllegalAccessException, 423 InvocationTargetException; 424 425 /** 426 * Returns a string containing a concise, human-readable description of this 427 * constructor. The format of the string is: 428 * 429 * <ol> 430 * <li>modifiers (if any) 431 * <li>declaring class name 432 * <li>'(' 433 * <li>parameter types, separated by ',' (if any) 434 * <li>')' 435 * <li>'throws' plus exception types, separated by ',' (if any) 436 * </ol> 437 * 438 * For example: 439 * {@code public String(byte[],String) throws UnsupportedEncodingException} 440 * 441 * @return a printable representation for this constructor 442 */ 443 @Override 444 public String toString() { 445 StringBuilder result = new StringBuilder(Modifier.toString(getModifiers())); 446 447 if (result.length() != 0) 448 result.append(' '); 449 result.append(declaringClass.getName()); 450 result.append("("); 451 result.append(toString(parameterTypes)); 452 result.append(")"); 453 if (exceptionTypes != null && exceptionTypes.length != 0) { 454 result.append(" throws "); 455 result.append(toString(exceptionTypes)); 456 } 457 458 return result.toString(); 459 } 460 }
Field程序員
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /* 18 * Copyright (C) 2008 The Android Open Source Project 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33 package java.lang.reflect; 34 35 import java.lang.annotation.Annotation; 36 import java.util.Comparator; 37 import org.apache.harmony.kernel.vm.StringUtils; 38 import org.apache.harmony.luni.lang.reflect.GenericSignatureParser; 39 import org.apache.harmony.luni.lang.reflect.Types; 40 41 /** 42 * This class represents a field. Information about the field can be accessed, 43 * and the field's value can be accessed dynamically. 44 */ 45 public final class Field extends AccessibleObject implements Member { 46 47 /** 48 * Orders fields by their name and declaring class. 49 * 50 * @hide 51 */ 52 public static final Comparator<Field> ORDER_BY_NAME_AND_DECLARING_CLASS 53 = new Comparator<Field>() { 54 @Override public int compare(Field a, Field b) { 55 int comparison = a.name.compareTo(b.name); 56 if (comparison != 0) { 57 return comparison; 58 } 59 60 return a.getDeclaringClass().getName().compareTo(b.getDeclaringClass().getName()); 61 } 62 }; 63 64 private Class<?> declaringClass; 65 66 private Class<?> type; 67 68 private Type genericType; 69 70 private volatile boolean genericTypesAreInitialized = false; 71 72 private String name; 73 74 private int slot; 75 76 private static final char TYPE_BOOLEAN = 'Z'; 77 78 private static final char TYPE_BYTE = 'B'; 79 80 private static final char TYPE_CHAR = 'C'; 81 82 private static final char TYPE_SHORT = 'S'; 83 84 private static final char TYPE_INTEGER = 'I'; 85 86 private static final char TYPE_FLOAT = 'F'; 87 88 private static final char TYPE_LONG = 'J'; 89 90 private static final char TYPE_DOUBLE = 'D'; 91 92 /** 93 * Construct a clone of the given instance. 94 * 95 * @param orig non-null; the original instance to clone 96 */ 97 /*package*/ Field(Field orig) { 98 this(orig.declaringClass, orig.type, orig.name, orig.slot); 99 100 // Copy the accessible flag. 101 if (orig.flag) { 102 this.flag = true; 103 } 104 } 105 106 private Field(Class<?> declaringClass, Class<?> type, String name, int slot) { 107 this.declaringClass = declaringClass; 108 this.type = type; 109 this.name = name; 110 this.slot = slot; 111 } 112 113 private synchronized void initGenericType() { 114 if (!genericTypesAreInitialized) { 115 String signatureAttribute = getSignatureAttribute(); 116 GenericSignatureParser parser = new GenericSignatureParser( 117 declaringClass.getClassLoader()); 118 parser.parseForField(this.declaringClass, signatureAttribute); 119 genericType = parser.fieldType; 120 if (genericType == null) { 121 genericType = getType(); 122 } 123 genericTypesAreInitialized = true; 124 } 125 } 126 127 /** {@inheritDoc} */ 128 @Override 129 /* package */String getSignatureAttribute() { 130 Object[] annotation = getSignatureAnnotation(declaringClass, slot); 131 132 if (annotation == null) { 133 return null; 134 } 135 136 return StringUtils.combineStrings(annotation); 137 } 138 139 /** 140 * Get the Signature annotation for this field. Returns null if not found. 141 */ 142 native private Object[] getSignatureAnnotation(Class declaringClass, int slot); 143 144 /** 145 * Indicates whether or not this field is synthetic. 146 * 147 * @return {@code true} if this field is synthetic, {@code false} otherwise 148 */ 149 public boolean isSynthetic() { 150 int flags = getFieldModifiers(declaringClass, slot); 151 return (flags & Modifier.SYNTHETIC) != 0; 152 } 153 154 /** 155 * Returns the string representation of this field, including the field's 156 * generic type. 157 * 158 * @return the string representation of this field 159 */ 160 public String toGenericString() { 161 StringBuilder sb = new StringBuilder(80); 162 // append modifiers if any 163 int modifier = getModifiers(); 164 if (modifier != 0) { 165 sb.append(Modifier.toString(modifier)).append(' '); 166 } 167 // append generic type 168 appendGenericType(sb, getGenericType()); 169 sb.append(' '); 170 // append full field name 171 sb.append(getDeclaringClass().getName()).append('.').append(getName()); 172 return sb.toString(); 173 } 174 175 /** 176 * Indicates whether or not this field is an enumeration constant. 177 * 178 * @return {@code true} if this field is an enumeration constant, {@code 179 * false} otherwise 180 */ 181 public boolean isEnumConstant() { 182 int flags = getFieldModifiers(declaringClass, slot); 183 return (flags & Modifier.ENUM) != 0; 184 } 185 186 /** 187 * Returns the generic type of this field. 188 * 189 * @return the generic type 190 * @throws GenericSignatureFormatError 191 * if the generic field signature is invalid 192 * @throws TypeNotPresentException 193 * if the generic type points to a missing type 194 * @throws MalformedParameterizedTypeException 195 * if the generic type points to a type that cannot be 196 * instantiated for some reason 197 */ 198 public Type getGenericType() { 199 initGenericType(); 200 return Types.getType(genericType); 201 } 202 203 @Override public Annotation[] getDeclaredAnnotations() { 204 return getDeclaredAnnotations(declaringClass, slot); 205 } 206 private static native Annotation[] getDeclaredAnnotations(Class declaringClass, int slot); 207 208 @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) { 209 if (annotationType == null) { 210 throw new NullPointerException("annotationType == null"); 211 } 212 return getAnnotation(declaringClass, slot, annotationType); 213 } 214 private static native <A extends Annotation> A getAnnotation( 215 Class<?> declaringClass, int slot, Class<A> annotationType); 216 217 @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) { 218 if (annotationType == null) { 219 throw new NullPointerException("annotationType == null"); 220 } 221 return isAnnotationPresent(declaringClass, slot, annotationType); 222 } 223 private static native boolean isAnnotationPresent( 224 Class<?> declaringClass, int slot, Class<? extends Annotation> annotationType); 225 226 /** 227 * Indicates whether or not the specified {@code object} is equal to this 228 * field. To be equal, the specified object must be an instance of 229 * {@code Field} with the same declaring class, type and name as this field. 230 * 231 * @param object 232 * the object to compare 233 * @return {@code true} if the specified object is equal to this method, 234 * {@code false} otherwise 235 * @see #hashCode 236 */ 237 @Override 238 public boolean equals(Object object) { 239 return object instanceof Field && toString().equals(object.toString()); 240 } 241 242 /** 243 * Returns the value of the field in the specified object. This reproduces 244 * the effect of {@code object.fieldName} 245 * 246 * <p>If the type of this field is a primitive type, the field value is 247 * automatically boxed. 248 * 249 * <p>If this field is static, the object argument is ignored. 250 * Otherwise, if the object is null, a NullPointerException is thrown. If 251 * the object is not an instance of the declaring class of the method, an 252 * IllegalArgumentException is thrown. 253 * 254 * <p>If this Field object is enforcing access control (see AccessibleObject) 255 * and this field is not accessible from the current context, an 256 * IllegalAccessException is thrown. 257 * 258 * @param object 259 * the object to access 260 * @return the field value, possibly boxed 261 * @throws NullPointerException 262 * if the object is {@code null} and the field is non-static 263 * @throws IllegalArgumentException 264 * if the object is not compatible with the declaring class 265 * @throws IllegalAccessException 266 * if this field is not accessible 267 */ 268 public Object get(Object object) throws IllegalAccessException, IllegalArgumentException { 269 return getField(object, declaringClass, type, slot, flag); 270 } 271 272 /** 273 * Returns the value of the field in the specified object as a {@code 274 * boolean}. This reproduces the effect of {@code object.fieldName} 275 * <p> 276 * If this field is static, the object argument is ignored. 277 * Otherwise, if the object is {@code null}, a NullPointerException is 278 * thrown. If the object is not an instance of the declaring class of the 279 * method, an IllegalArgumentException is thrown. 280 * <p> 281 * If this Field object is enforcing access control (see AccessibleObject) 282 * and this field is not accessible from the current context, an 283 * IllegalAccessException is thrown. 284 * 285 * @param object 286 * the object to access 287 * @return the field value 288 * @throws NullPointerException 289 * if the object is {@code null} and the field is non-static 290 * @throws IllegalArgumentException 291 * if the object is not compatible with the declaring class 292 * @throws IllegalAccessException 293 * if this field is not accessible 294 */ 295 public boolean getBoolean(Object object) throws IllegalAccessException, 296 IllegalArgumentException { 297 return getZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN); 298 } 299 300 /** 301 * Returns the value of the field in the specified object as a {@code byte}. 302 * This reproduces the effect of {@code object.fieldName} 303 * <p> 304 * If this field is static, the object argument is ignored. 305 * Otherwise, if the object is {@code null}, a NullPointerException is 306 * thrown. If the object is not an instance of the declaring class of the 307 * method, an IllegalArgumentException is thrown. 308 * <p> 309 * If this Field object is enforcing access control (see AccessibleObject) 310 * and this field is not accessible from the current context, an 311 * IllegalAccessException is thrown. 312 * 313 * @param object 314 * the object to access 315 * @return the field value 316 * @throws NullPointerException 317 * if the object is {@code null} and the field is non-static 318 * @throws IllegalArgumentException 319 * if the object is not compatible with the declaring class 320 * @throws IllegalAccessException 321 * if this field is not accessible 322 */ 323 public byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException { 324 return getBField(object, declaringClass, type, slot, flag, TYPE_BYTE); 325 } 326 327 /** 328 * Returns the value of the field in the specified object as a {@code char}. 329 * This reproduces the effect of {@code object.fieldName} 330 * <p> 331 * If this field is static, the object argument is ignored. 332 * Otherwise, if the object is {@code null}, a NullPointerException is 333 * thrown. If the object is not an instance of the declaring class of the 334 * method, an IllegalArgumentException is thrown. 335 * <p> 336 * If this Field object is enforcing access control (see AccessibleObject) 337 * and this field is not accessible from the current context, an 338 * IllegalAccessException is thrown. 339 * 340 * @param object 341 * the object to access 342 * @return the field value 343 * @throws NullPointerException 344 * if the object is {@code null} and the field is non-static 345 * @throws IllegalArgumentException 346 * if the object is not compatible with the declaring class 347 * @throws IllegalAccessException 348 * if this field is not accessible 349 */ 350 public char getChar(Object object) throws IllegalAccessException, IllegalArgumentException { 351 return getCField(object, declaringClass, type, slot, flag, TYPE_CHAR); 352 } 353 354 /** 355 * Returns the class that declares this field. 356 * 357 * @return the declaring class 358 */ 359 public Class<?> getDeclaringClass() { 360 return declaringClass; 361 } 362 363 /** 364 * Returns the value of the field in the specified object as a {@code 365 * double}. This reproduces the effect of {@code object.fieldName} 366 * <p> 367 * If this field is static, the object argument is ignored. 368 * Otherwise, if the object is {@code null}, a NullPointerException is 369 * thrown. If the object is not an instance of the declaring class of the 370 * method, an IllegalArgumentException is thrown. 371 * <p> 372 * If this Field object is enforcing access control (see AccessibleObject) 373 * and this field is not accessible from the current context, an 374 * IllegalAccessException is thrown. 375 * 376 * @param object 377 * the object to access 378 * @return the field value 379 * @throws NullPointerException 380 * if the object is {@code null} and the field is non-static 381 * @throws IllegalArgumentException 382 * if the object is not compatible with the declaring class 383 * @throws IllegalAccessException 384 * if this field is not accessible 385 */ 386 public double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException { 387 return getDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE); 388 } 389 390 /** 391 * Returns the value of the field in the specified object as a {@code float} 392 * . This reproduces the effect of {@code object.fieldName} 393 * <p> 394 * If this field is static, the object argument is ignored. 395 * Otherwise, if the object is {@code null}, a NullPointerException is 396 * thrown. If the object is not an instance of the declaring class of the 397 * method, an IllegalArgumentException is thrown. 398 * <p> 399 * If this Field object is enforcing access control (see AccessibleObject) 400 * and this field is not accessible from the current context, an 401 * IllegalAccessException is thrown. 402 * 403 * @param object 404 * the object to access 405 * @return the field value 406 * @throws NullPointerException 407 * if the object is {@code null} and the field is non-static 408 * @throws IllegalArgumentException 409 * if the object is not compatible with the declaring class 410 * @throws IllegalAccessException 411 * if this field is not accessible 412 */ 413 public float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException { 414 return getFField(object, declaringClass, type, slot, flag, TYPE_FLOAT); 415 } 416 417 /** 418 * Returns the value of the field in the specified object as an {@code int}. 419 * This reproduces the effect of {@code object.fieldName} 420 * <p> 421 * If this field is static, the object argument is ignored. 422 * Otherwise, if the object is {@code null}, a NullPointerException is 423 * thrown. If the object is not an instance of the declaring class of the 424 * method, an IllegalArgumentException is thrown. 425 * <p> 426 * If this Field object is enforcing access control (see AccessibleObject) 427 * and this field is not accessible from the current context, an 428 * IllegalAccessException is thrown. 429 * 430 * @param object 431 * the object to access 432 * @return the field value 433 * @throws NullPointerException 434 * if the object is {@code null} and the field is non-static 435 * @throws IllegalArgumentException 436 * if the object is not compatible with the declaring class 437 * @throws IllegalAccessException 438 * if this field is not accessible 439 */ 440 public int getInt(Object object) throws IllegalAccessException, IllegalArgumentException { 441 return getIField(object, declaringClass, type, slot, flag, TYPE_INTEGER); 442 } 443 444 /** 445 * Returns the value of the field in the specified object as a {@code long}. 446 * This reproduces the effect of {@code object.fieldName} 447 * <p> 448 * If this field is static, the object argument is ignored. 449 * Otherwise, if the object is {@code null}, a NullPointerException is 450 * thrown. If the object is not an instance of the declaring class of the 451 * method, an IllegalArgumentException is thrown. 452 * <p> 453 * If this Field object is enforcing access control (see AccessibleObject) 454 * and this field is not accessible from the current context, an 455 * IllegalAccessException is thrown. 456 * 457 * @param object 458 * the object to access 459 * @return the field value 460 * @throws NullPointerException 461 * if the object is {@code null} and the field is non-static 462 * @throws IllegalArgumentException 463 * if the object is not compatible with the declaring class 464 * @throws IllegalAccessException 465 * if this field is not accessible 466 */ 467 public long getLong(Object object) throws IllegalAccessException, IllegalArgumentException { 468 return getJField(object, declaringClass, type, slot, flag, TYPE_LONG); 469 } 470 471 /** 472 * Returns the modifiers for this field. The {@link Modifier} class should 473 * be used to decode the result. 474 * 475 * @return the modifiers for this field 476 * @see Modifier 477 */ 478 public int getModifiers() { 479 return getFieldModifiers(declaringClass, slot); 480 } 481 482 private native int getFieldModifiers(Class<?> declaringClass, int slot); 483 484 /** 485 * Returns the name of this field. 486 * 487 * @return the name of this field 488 */ 489 public String getName() { 490 return name; 491 } 492 493 /** 494 * Returns the value of the field in the specified object as a {@code short} 495 * . This reproduces the effect of {@code object.fieldName} 496 * <p> 497 * If this field is static, the object argument is ignored. 498 * Otherwise, if the object is {@code null}, a NullPointerException is 499 * thrown. If the object is not an instance of the declaring class of the 500 * method, an IllegalArgumentException is thrown. 501 * <p> 502 * If this Field object is enforcing access control (see AccessibleObject) 503 * and this field is not accessible from the current context, an 504 * IllegalAccessException is thrown. 505 * 506 * @param object 507 * the object to access 508 * @return the field value 509 * @throws NullPointerException 510 * if the object is {@code null} and the field is non-static 511 * @throws IllegalArgumentException 512 * if the object is not compatible with the declaring class 513 * @throws IllegalAccessException 514 * if this field is not accessible 515 */ 516 public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException { 517 return getSField(object, declaringClass, type, slot, flag, TYPE_SHORT); 518 } 519 520 /** 521 * Returns the constructor's signature in non-printable form. This is called 522 * (only) from IO native code and needed for deriving the serialVersionUID 523 * of the class 524 * 525 * @return the constructor's signature. 526 */ 527 @SuppressWarnings("unused") 528 private String getSignature() { 529 return getSignature(type); 530 } 531 532 /** 533 * Return the {@link Class} associated with the type of this field. 534 * 535 * @return the type of this field 536 */ 537 public Class<?> getType() { 538 return type; 539 } 540 541 /** 542 * Returns an integer hash code for this field. Objects which are equal 543 * return the same value for this method. 544 * <p> 545 * The hash code for a Field is the exclusive-or combination of the hash 546 * code of the field's name and the hash code of the name of its declaring 547 * class. 548 * 549 * @return the hash code for this field 550 * @see #equals 551 */ 552 @Override 553 public int hashCode() { 554 return name.hashCode() ^ getDeclaringClass().getName().hashCode(); 555 } 556 557 /** 558 * Sets the value of the field in the specified object to the value. This 559 * reproduces the effect of {@code object.fieldName = value} 560 * 561 * <p>If this field is static, the object argument is ignored. 562 * Otherwise, if the object is {@code null}, a NullPointerException is 563 * thrown. If the object is not an instance of the declaring class of the 564 * method, an IllegalArgumentException is thrown. 565 * 566 * <p>If this Field object is enforcing access control (see AccessibleObject) 567 * and this field is not accessible from the current context, an 568 * IllegalAccessException is thrown. 569 * 570 * <p>If the field type is a primitive type, the value is automatically 571 * unboxed. If the unboxing fails, an IllegalArgumentException is thrown. If 572 * the value cannot be converted to the field type via a widening 573 * conversion, an IllegalArgumentException is thrown. 574 * 575 * @param object 576 * the object to access 577 * @param value 578 * the new value 579 * @throws NullPointerException 580 * if the object is {@code null} and the field is non-static 581 * @throws IllegalArgumentException 582 * if the object is not compatible with the declaring class 583 * @throws IllegalAccessException 584 * if this field is not accessible 585 */ 586 public void set(Object object, Object value) throws IllegalAccessException, 587 IllegalArgumentException { 588 setField(object, declaringClass, type, slot, flag, value); 589 } 590 591 /** 592 * Sets the value of the field in the specified object to the {@code 593 * boolean} value. This reproduces the effect of {@code object.fieldName = 594 * value} 595 * <p> 596 * If this field is static, the object argument is ignored. 597 * Otherwise, if the object is {@code null}, a NullPointerException is 598 * thrown. If the object is not an instance of the declaring class of the 599 * method, an IllegalArgumentException is thrown. 600 * <p> 601 * If this Field object is enforcing access control (see AccessibleObject) 602 * and this field is not accessible from the current context, an 603 * IllegalAccessException is thrown. 604 * <p> 605 * If the value cannot be converted to the field type via a widening 606 * conversion, an IllegalArgumentException is thrown. 607 * 608 * @param object 609 * the object to access 610 * @param value 611 * the new value 612 * @throws NullPointerException 613 * if the object is {@code null} and the field is non-static 614 * @throws IllegalArgumentException 615 * if the object is not compatible with the declaring class 616 * @throws IllegalAccessException 617 * if this field is not accessible 618 */ 619 public void setBoolean(Object object, boolean value) throws IllegalAccessException, 620 IllegalArgumentException { 621 setZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN, value); 622 } 623 624 /** 625 * Sets the value of the field in the specified object to the {@code byte} 626 * value. This reproduces the effect of {@code object.fieldName = value} 627 * <p> 628 * If this field is static, the object argument is ignored. 629 * Otherwise, if the object is {@code null}, a NullPointerException is 630 * thrown. If the object is not an instance of the declaring class of the 631 * method, an IllegalArgumentException is thrown. 632 * <p> 633 * If this Field object is enforcing access control (see AccessibleObject) 634 * and this field is not accessible from the current context, an 635 * IllegalAccessException is thrown. 636 * <p> 637 * If the value cannot be converted to the field type via a widening 638 * conversion, an IllegalArgumentException is thrown. 639 * 640 * @param object 641 * the object to access 642 * @param value 643 * the new value 644 * @throws NullPointerException 645 * if the object is {@code null} and the field is non-static 646 * @throws IllegalArgumentException 647 * if the object is not compatible with the declaring class 648 * @throws IllegalAccessException 649 * if this field is not accessible 650 */ 651 public void setByte(Object object, byte value) throws IllegalAccessException, 652 IllegalArgumentException { 653 setBField(object, declaringClass, type, slot, flag, TYPE_BYTE, value); 654 } 655 656 /** 657 * Sets the value of the field in the specified object to the {@code char} 658 * value. This reproduces the effect of {@code object.fieldName = value} 659 * <p> 660 * If this field is static, the object argument is ignored. 661 * Otherwise, if the object is {@code null}, a NullPointerException is 662 * thrown. If the object is not an instance of the declaring class of the 663 * method, an IllegalArgumentException is thrown. 664 * <p> 665 * If this Field object is enforcing access control (see AccessibleObject) 666 * and this field is not accessible from the current context, an 667 * IllegalAccessException is thrown. 668 * <p> 669 * If the value cannot be converted to the field type via a widening 670 * conversion, an IllegalArgumentException is thrown. 671 * 672 * @param object 673 * the object to access 674 * @param value 675 * the new value 676 * @throws NullPointerException 677 * if the object is {@code null} and the field is non-static 678 * @throws IllegalArgumentException 679 * if the object is not compatible with the declaring class 680 * @throws IllegalAccessException 681 * if this field is not accessible 682 */ 683 public void setChar(Object object, char value) throws IllegalAccessException, 684 IllegalArgumentException { 685 setCField(object, declaringClass, type, slot, flag, TYPE_CHAR, value); 686 } 687 688 /** 689 * Sets the value of the field in the specified object to the {@code double} 690 * value. This reproduces the effect of {@code object.fieldName = value} 691 * <p> 692 * If this field is static, the object argument is ignored. 693 * Otherwise, if the object is {@code null}, a NullPointerException is 694 * thrown. If the object is not an instance of the declaring class of the 695 * method, an IllegalArgumentException is thrown. 696 * <p> 697 * If this Field object is enforcing access control (see AccessibleObject) 698 * and this field is not accessible from the current context, an 699 * IllegalAccessException is thrown. 700 * <p> 701 * If the value cannot be converted to the field type via a widening 702 * conversion, an IllegalArgumentException is thrown. 703 * 704 * @param object 705 * the object to access 706 * @param value 707 * the new value 708 * @throws NullPointerException 709 * if the object is {@code null} and the field is non-static 710 * @throws IllegalArgumentException 711 * if the object is not compatible with the declaring class 712 * @throws IllegalAccessException 713 * if this field is not accessible 714 */ 715 public void setDouble(Object object, double value) throws IllegalAccessException, 716 IllegalArgumentException { 717 setDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE, value); 718 } 719 720 /** 721 * Sets the value of the field in the specified object to the {@code float} 722 * value. This reproduces the effect of {@code object.fieldName = value} 723 * <p> 724 * If this field is static, the object argument is ignored. 725 * Otherwise, if the object is {@code null}, a NullPointerException is 726 * thrown. If the object is not an instance of the declaring class of the 727 * method, an IllegalArgumentException is thrown. 728 * <p> 729 * If this Field object is enforcing access control (see AccessibleObject) 730 * and this field is not accessible from the current context, an 731 * IllegalAccessException is thrown. 732 * <p> 733 * If the value cannot be converted to the field type via a widening 734 * conversion, an IllegalArgumentException is thrown. 735 * 736 * @param object 737 * the object to access 738 * @param value 739 * the new value 740 * @throws NullPointerException 741 * if the object is {@code null} and the field is non-static 742 * @throws IllegalArgumentException 743 * if the object is not compatible with the declaring class 744 * @throws IllegalAccessException 745 * if this field is not accessible 746 */ 747 public void setFloat(Object object, float value) throws IllegalAccessException, 748 IllegalArgumentException { 749 setFField(object, declaringClass, type, slot, flag, TYPE_FLOAT, value); 750 } 751 752 /** 753 * Set the value of the field in the specified object to the {@code int} 754 * value. This reproduces the effect of {@code object.fieldName = value} 755 * <p> 756 * If this field is static, the object argument is ignored. 757 * Otherwise, if the object is {@code null}, a NullPointerException is 758 * thrown. If the object is not an instance of the declaring class of the 759 * method, an IllegalArgumentException is thrown. 760 * <p> 761 * If this Field object is enforcing access control (see AccessibleObject) 762 * and this field is not accessible from the current context, an 763 * IllegalAccessException is thrown. 764 * <p> 765 * If the value cannot be converted to the field type via a widening 766 * conversion, an IllegalArgumentException is thrown. 767 * 768 * @param object 769 * the object to access 770 * @param value 771 * the new value 772 * @throws NullPointerException 773 * if the object is {@code null} and the field is non-static 774 * @throws IllegalArgumentException 775 * if the object is not compatible with the declaring class 776 * @throws IllegalAccessException 777 * if this field is not accessible 778 */ 779 public void setInt(Object object, int value) throws IllegalAccessException, 780 IllegalArgumentException { 781 setIField(object, declaringClass, type, slot, flag, TYPE_INTEGER, value); 782 } 783 784 /** 785 * Sets the value of the field in the specified object to the {@code long} 786 * value. This reproduces the effect of {@code object.fieldName = value} 787 * <p> 788 * If this field is static, the object argument is ignored. 789 * Otherwise, if the object is {@code null}, a NullPointerException is 790 * thrown. If the object is not an instance of the declaring class of the 791 * method, an IllegalArgumentException is thrown. 792 * <p> 793 * If this Field object is enforcing access control (see AccessibleObject) 794 * and this field is not accessible from the current context, an 795 * IllegalAccessException is thrown. 796 * <p> 797 * If the value cannot be converted to the field type via a widening 798 * conversion, an IllegalArgumentException is thrown. 799 * 800 * @param object 801 * the object to access 802 * @param value 803 * the new value 804 * @throws NullPointerException 805 * if the object is {@code null} and the field is non-static 806 * @throws IllegalArgumentException 807 * if the object is not compatible with the declaring class 808 * @throws IllegalAccessException 809 * if this field is not accessible 810 */ 811 public void setLong(Object object, long value) throws IllegalAccessException, 812 IllegalArgumentException { 813 setJField(object, declaringClass, type, slot, flag, TYPE_LONG, value); 814 } 815 816 /** 817 * Sets the value of the field in the specified object to the {@code short} 818 * value. This reproduces the effect of {@code object.fieldName = value} 819 * <p> 820 * If this field is static, the object argument is ignored. 821 * Otherwise, if the object is {@code null}, a NullPointerException is 822 * thrown. If the object is not an instance of the declaring class of the 823 * method, an IllegalArgumentException is thrown. 824 * <p> 825 * If this Field object is enforcing access control (see AccessibleObject) 826 * and this field is not accessible from the current context, an 827 * IllegalAccessException is thrown. 828 * <p> 829 * If the value cannot be converted to the field type via a widening 830 * conversion, an IllegalArgumentException is thrown. 831 * 832 * @param object 833 * the object to access 834 * @param value 835 * the new value 836 * @throws NullPointerException 837 * if the object is {@code null} and the field is non-static 838 * @throws IllegalArgumentException 839 * if the object is not compatible with the declaring class 840 * @throws IllegalAccessException 841 * if this field is not accessible 842 */ 843 public void setShort(Object object, short value) throws IllegalAccessException, 844 IllegalArgumentException { 845 setSField(object, declaringClass, type, slot, flag, TYPE_SHORT, value); 846 } 847 848 /** 849 * Returns a string containing a concise, human-readable description of this 850 * field. 851 * <p> 852 * The format of the string is: 853 * <ol> 854 * <li>modifiers (if any) 855 * <li>type 856 * <li>declaring class name 857 * <li>'.' 858 * <li>field name 859 * </ol> 860 * <p> 861 * For example: {@code public static java.io.InputStream 862 * java.lang.System.in} 863 * 864 * @return a printable representation for this field 865 */ 866 @Override 867 public String toString() { 868 StringBuilder result = new StringBuilder(Modifier.toString(getModifiers())); 869 if (result.length() != 0) { 870 result.append(' '); 871 } 872 appendArrayType(result, type); 873 result.append(' '); 874 result.append(declaringClass.getName()); 875 result.append('.'); 876 result.append(name); 877 return result.toString(); 878 } 879 880 private native Object getField(Object o, Class<?> declaringClass, Class<?> type, int slot, 881 boolean noAccessCheck) throws IllegalAccessException; 882 883 private native double getDField(Object o, Class<?> declaringClass, Class<?> type, int slot, 884 boolean noAccessCheck, char descriptor) throws IllegalAccessException; 885 886 private native int getIField(Object o, Class<?> declaringClass, Class<?> type, int slot, 887 boolean noAccessCheck, char descriptor) throws IllegalAccessException; 888 889 private native long getJField(Object o, Class<?> declaringClass, Class<?> type, int slot, 890 boolean noAccessCheck, char descriptor) throws IllegalAccessException; 891 892 private native boolean getZField(Object o, Class<?> declaringClass, Class<?> type, int slot, 893 boolean noAccessCheck, char descriptor) throws IllegalAccessException; 894 895 private native float getFField(Object o, Class<?> declaringClass, Class<?> type, int slot, 896 boolean noAccessCheck, char descriptor) throws IllegalAccessException; 897 898 private native char getCField(Object o, Class<?> declaringClass, Class<?> type, int slot, 899 boolean noAccessCheck, char descriptor) throws IllegalAccessException; 900 901 private native short getSField(Object o, Class<?> declaringClass, Class<?> type, int slot, 902 boolean noAccessCheck, char descriptor) throws IllegalAccessException; 903 904 private native byte getBField(Object o, Class<?> declaringClass, Class<?> type, int slot, 905 boolean noAccessCheck, char descriptor) throws IllegalAccessException; 906 907 private native void setField(Object o, Class<?> declaringClass, Class<?> type, int slot, 908 boolean noAccessCheck, Object value) throws IllegalAccessException; 909 910 private native void setDField(Object o, Class<?> declaringClass, Class<?> type, int slot, 911 boolean noAccessCheck, char descriptor, double v) throws IllegalAccessException; 912 913 private native void setIField(Object o, Class<?> declaringClass, Class<?> type, int slot, 914 boolean noAccessCheck, char descriptor, int i) throws IllegalAccessException; 915 916 private native void setJField(Object o, Class<?> declaringClass, Class<?> type, int slot, 917 boolean noAccessCheck, char descriptor, long j) throws IllegalAccessException; 918 919 private native void setZField(Object o, Class<?> declaringClass, Class<?> type, int slot, 920 boolean noAccessCheck, char descriptor, boolean z) throws IllegalAccessException; 921 922 private native void setFField(Object o, Class<?> declaringClass, Class<?> type, int slot, 923 boolean noAccessCheck, char descriptor, float f) throws IllegalAccessException; 924 925 private native void setCField(Object o, Class<?> declaringClass, Class<?> type, int slot, 926 boolean noAccessCheck, char descriptor, char c) throws IllegalAccessException; 927 928 private native void setSField(Object o, Class<?> declaringClass, Class<?> type, int slot, 929 boolean noAccessCheck, char descriptor, short s) throws IllegalAccessException; 930 931 private native void setBField(Object o, Class<?> declaringClass, Class<?> type, int slot, 932 boolean noAccessCheck, char descriptor, byte b) throws IllegalAccessException; 933 934 }
Memberexpress
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.lang.reflect; 19 20 /** 21 * Common interface providing access to reflective information on class members. 22 * 23 * @see Field 24 * @see Constructor 25 * @see Method 26 */ 27 public interface Member { 28 29 /** 30 * Designates all public members of a class or interface (including 31 * inherited members). 32 */ 33 public static final int PUBLIC = 0; 34 35 /** 36 * Designates all declared members of a class or interface (without 37 * inherited members). 38 */ 39 public static final int DECLARED = 1; 40 41 /** 42 * Returns the class that declares this member. 43 * 44 * @return the declaring class 45 */ 46 @SuppressWarnings("unchecked") 47 Class<?> getDeclaringClass(); 48 49 /** 50 * Returns the modifiers for this member. The {@link Modifier} class should 51 * be used to decode the result. 52 * 53 * @return the modifiers for this member 54 * 55 * @see Modifier 56 */ 57 int getModifiers(); 58 59 /** 60 * Returns the name of this member. 61 * 62 * @return the name of this member 63 */ 64 String getName(); 65 66 /** 67 * Indicates whether or not this member is synthetic (artificially 68 * introduced by the compiler). 69 * 70 * @return {@code true} if this member is synthetic, {@code false} otherwise 71 */ 72 boolean isSynthetic(); 73 }
Methodapache
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /* 18 * Copyright (C) 2008 The Android Open Source Project 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33 package java.lang.reflect; 34 35 import java.lang.annotation.Annotation; 36 import java.util.Comparator; 37 import libcore.util.EmptyArray; 38 import org.apache.harmony.kernel.vm.StringUtils; 39 import org.apache.harmony.luni.lang.reflect.GenericSignatureParser; 40 import org.apache.harmony.luni.lang.reflect.ListOfTypes; 41 import org.apache.harmony.luni.lang.reflect.Types; 42 43 /** 44 * This class represents a method. Information about the method can be accessed, 45 * and the method can be invoked dynamically. 46 */ 47 public final class Method extends AccessibleObject implements GenericDeclaration, Member { 48 49 /** 50 * Orders methods by their name, parameters and return type. 51 * 52 * @hide 53 */ 54 public static final Comparator<Method> ORDER_BY_SIGNATURE = new Comparator<Method>() { 55 public int compare(Method a, Method b) { 56 int comparison = a.name.compareTo(b.name); 57 if (comparison != 0) { 58 return comparison; 59 } 60 61 Class<?>[] aParameters = a.parameterTypes; 62 Class<?>[] bParameters = b.parameterTypes; 63 int length = Math.min(aParameters.length, bParameters.length); 64 for (int i = 0; i < length; i++) { 65 comparison = aParameters[i].getName().compareTo(bParameters[i].getName()); 66 if (comparison != 0) { 67 return comparison; 68 } 69 } 70 71 if (aParameters.length != bParameters.length) { 72 return aParameters.length - bParameters.length; 73 } 74 75 // this is necessary for methods that have covariant return types. 76 return a.getReturnType().getName().compareTo(b.getReturnType().getName()); 77 } 78 }; 79 80 private int slot; 81 82 private Class<?> declaringClass; 83 84 private String name; 85 86 private Class<?>[] parameterTypes; 87 88 private Class<?>[] exceptionTypes; 89 90 private Class<?> returnType; 91 92 private ListOfTypes genericExceptionTypes; 93 private ListOfTypes genericParameterTypes; 94 private Type genericReturnType; 95 private TypeVariable<Method>[] formalTypeParameters; 96 private volatile boolean genericTypesAreInitialized = false; 97 98 private synchronized void initGenericTypes() { 99 if (!genericTypesAreInitialized) { 100 String signatureAttribute = getSignatureAttribute(); 101 GenericSignatureParser parser = new GenericSignatureParser( 102 declaringClass.getClassLoader()); 103 parser.parseForMethod(this, signatureAttribute, exceptionTypes); 104 formalTypeParameters = parser.formalTypeParameters; 105 genericParameterTypes = parser.parameterTypes; 106 genericExceptionTypes = parser.exceptionTypes; 107 genericReturnType = parser.returnType; 108 genericTypesAreInitialized = true; 109 } 110 } 111 112 /** 113 * Construct a clone of the given instance. 114 * 115 * @param orig non-null; the original instance to clone 116 */ 117 /*package*/ Method(Method orig) { 118 this(orig.declaringClass, orig.parameterTypes, orig.exceptionTypes, 119 orig.returnType, orig.name, orig.slot); 120 121 // Copy the accessible flag. 122 if (orig.flag) { 123 this.flag = true; 124 } 125 } 126 127 private Method(Class<?> declaring, Class<?>[] paramTypes, Class<?>[] exceptTypes, Class<?> returnType, String name, int slot) 128 { 129 this.declaringClass = declaring; 130 this.name = name; 131 this.slot = slot; 132 this.parameterTypes = paramTypes; 133 this.exceptionTypes = exceptTypes; // may be null 134 this.returnType = returnType; 135 } 136 137 public TypeVariable<Method>[] getTypeParameters() { 138 initGenericTypes(); 139 return formalTypeParameters.clone(); 140 } 141 142 /** {@inheritDoc} */ 143 @Override /*package*/ String getSignatureAttribute() { 144 Object[] annotation = getSignatureAnnotation(declaringClass, slot); 145 146 if (annotation == null) { 147 return null; 148 } 149 150 return StringUtils.combineStrings(annotation); 151 } 152 153 /** 154 * Returns the Signature annotation for this method. Returns {@code null} if 155 * not found. 156 */ 157 static native Object[] getSignatureAnnotation(Class declaringClass, int slot); 158 159 /** 160 * Returns the string representation of the method's declaration, including 161 * the type parameters. 162 * 163 * @return the string representation of this method 164 */ 165 public String toGenericString() { 166 StringBuilder sb = new StringBuilder(80); 167 168 initGenericTypes(); 169 170 // append modifiers if any 171 int modifier = getModifiers(); 172 if (modifier != 0) { 173 sb.append(Modifier.toString(modifier & ~(Modifier.BRIDGE + 174 Modifier.VARARGS))).append(' '); 175 } 176 // append type parameters 177 if (formalTypeParameters != null && formalTypeParameters.length > 0) { 178 sb.append('<'); 179 for (int i = 0; i < formalTypeParameters.length; i++) { 180 appendGenericType(sb, formalTypeParameters[i]); 181 if (i < formalTypeParameters.length - 1) { 182 sb.append(","); 183 } 184 } 185 sb.append("> "); 186 } 187 // append return type 188 appendGenericType(sb, Types.getType(genericReturnType)); 189 sb.append(' '); 190 // append method name 191 appendArrayType(sb, getDeclaringClass()); 192 sb.append(".").append(getName()); 193 // append parameters 194 sb.append('('); 195 appendArrayGenericType(sb, 196 Types.getClonedTypeArray(genericParameterTypes)); 197 sb.append(')'); 198 // append exceptions if any 199 Type[] genericExceptionTypeArray = Types.getClonedTypeArray( 200 genericExceptionTypes); 201 if (genericExceptionTypeArray.length > 0) { 202 sb.append(" throws "); 203 appendArrayGenericType(sb, genericExceptionTypeArray); 204 } 205 return sb.toString(); 206 } 207 208 /** 209 * Returns the parameter types as an array of {@code Type} instances, in 210 * declaration order. If this method has no parameters, an empty array is 211 * returned. 212 * 213 * @return the parameter types 214 * 215 * @throws GenericSignatureFormatError 216 * if the generic method signature is invalid 217 * @throws TypeNotPresentException 218 * if any parameter type points to a missing type 219 * @throws MalformedParameterizedTypeException 220 * if any parameter type points to a type that cannot be 221 * instantiated for some reason 222 */ 223 public Type[] getGenericParameterTypes() { 224 initGenericTypes(); 225 return Types.getClonedTypeArray(genericParameterTypes); 226 } 227 228 /** 229 * Returns the exception types as an array of {@code Type} instances. If 230 * this method has no declared exceptions, an empty array will be returned. 231 * 232 * @return an array of generic exception types 233 * 234 * @throws GenericSignatureFormatError 235 * if the generic method signature is invalid 236 * @throws TypeNotPresentException 237 * if any exception type points to a missing type 238 * @throws MalformedParameterizedTypeException 239 * if any exception type points to a type that cannot be 240 * instantiated for some reason 241 */ 242 public Type[] getGenericExceptionTypes() { 243 initGenericTypes(); 244 return Types.getClonedTypeArray(genericExceptionTypes); 245 } 246 247 /** 248 * Returns the return type of this method as a {@code Type} instance. 249 * 250 * @return the return type of this method 251 * 252 * @throws GenericSignatureFormatError 253 * if the generic method signature is invalid 254 * @throws TypeNotPresentException 255 * if the return type points to a missing type 256 * @throws MalformedParameterizedTypeException 257 * if the return type points to a type that cannot be 258 * instantiated for some reason 259 */ 260 public Type getGenericReturnType() { 261 initGenericTypes(); 262 return Types.getType(genericReturnType); 263 } 264 265 @Override 266 public Annotation[] getDeclaredAnnotations() { 267 return getDeclaredAnnotations(declaringClass, slot); 268 } 269 static native Annotation[] getDeclaredAnnotations(Class<?> declaringClass, int slot); 270 271 @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) { 272 if (annotationType == null) { 273 throw new NullPointerException("annotationType == null"); 274 } 275 return getAnnotation(declaringClass, slot, annotationType); 276 } 277 static native <A extends Annotation> A getAnnotation( 278 Class<?> declaringClass, int slot, Class<A> annotationType); 279 280 @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) { 281 if (annotationType == null) { 282 throw new NullPointerException("annotationType == null"); 283 } 284 return isAnnotationPresent(declaringClass, slot, annotationType); 285 } 286 static native boolean isAnnotationPresent( 287 Class<?> declaringClass, int slot, Class<? extends Annotation> annotationType); 288 289 private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; 290 291 /** 292 * Creates an array of empty Annotation arrays. 293 */ 294 /*package*/ static Annotation[][] noAnnotations(int size) { 295 Annotation[][] annotations = new Annotation[size][]; 296 for (int i = 0; i < size; i++) { 297 annotations[i] = NO_ANNOTATIONS; 298 } 299 return annotations; 300 } 301 302 /** 303 * Returns an array of arrays that represent the annotations of the formal 304 * parameters of this method. If there are no parameters on this method, 305 * then an empty array is returned. If there are no annotations set, then 306 * and array of empty arrays is returned. 307 * 308 * @return an array of arrays of {@code Annotation} instances 309 */ 310 public Annotation[][] getParameterAnnotations() { 311 Annotation[][] parameterAnnotations 312 = getParameterAnnotations(declaringClass, slot); 313 if (parameterAnnotations.length == 0) { 314 return noAnnotations(parameterTypes.length); 315 } 316 return parameterAnnotations; 317 } 318 319 static native Annotation[][] getParameterAnnotations(Class declaringClass, int slot); 320 321 /** 322 * Indicates whether or not this method takes a variable number argument. 323 * 324 * @return {@code true} if a vararg is declared, {@code false} otherwise 325 */ 326 public boolean isVarArgs() { 327 int modifiers = getMethodModifiers(declaringClass, slot); 328 return (modifiers & Modifier.VARARGS) != 0; 329 } 330 331 /** 332 * Indicates whether or not this method is a bridge. 333 * 334 * @return {@code true} if this method is a bridge, {@code false} otherwise 335 */ 336 public boolean isBridge() { 337 int modifiers = getMethodModifiers(declaringClass, slot); 338 return (modifiers & Modifier.BRIDGE) != 0; 339 } 340 341 /** 342 * Indicates whether or not this method is synthetic. 343 * 344 * @return {@code true} if this method is synthetic, {@code false} otherwise 345 */ 346 public boolean isSynthetic() { 347 int modifiers = getMethodModifiers(declaringClass, slot); 348 return (modifiers & Modifier.SYNTHETIC) != 0; 349 } 350 351 /** 352 * Returns the default value for the annotation member represented by this 353 * method. 354 * 355 * @return the default value, or {@code null} if none 356 * 357 * @throws TypeNotPresentException 358 * if this annotation member is of type {@code Class} and no 359 * definition can be found 360 */ 361 public Object getDefaultValue() { 362 return getDefaultValue(declaringClass, slot); 363 } 364 native private Object getDefaultValue(Class declaringClass, int slot); 365 366 /** 367 * Indicates whether or not the specified {@code object} is equal to this 368 * method. To be equal, the specified object must be an instance 369 * of {@code Method} with the same declaring class and parameter types 370 * as this method. 371 * 372 * @param object 373 * the object to compare 374 * 375 * @return {@code true} if the specified object is equal to this 376 * method, {@code false} otherwise 377 * 378 * @see #hashCode 379 */ 380 @Override 381 public boolean equals(Object object) { 382 return object instanceof Method && toString().equals(object.toString()); 383 } 384 385 /** 386 * Returns the class that declares this method. 387 * 388 * @return the declaring class 389 */ 390 public Class<?> getDeclaringClass() { 391 return declaringClass; 392 } 393 394 /** 395 * Returns the exception types as an array of {@code Class} instances. If 396 * this method has no declared exceptions, an empty array is returned. 397 * 398 * @return the declared exception classes 399 */ 400 public Class<?>[] getExceptionTypes() { 401 if (exceptionTypes == null) { 402 return EmptyArray.CLASS; 403 } 404 return exceptionTypes.clone(); 405 } 406 407 /** 408 * Returns the modifiers for this method. The {@link Modifier} class should 409 * be used to decode the result. 410 * 411 * @return the modifiers for this method 412 * 413 * @see Modifier 414 */ 415 public int getModifiers() { 416 return getMethodModifiers(declaringClass, slot); 417 } 418 419 static native int getMethodModifiers(Class<?> declaringClass, int slot); 420 421 /** 422 * Returns the name of the method represented by this {@code Method} 423 * instance. 424 * 425 * @return the name of this method 426 */ 427 public String getName() { 428 return name; 429 } 430 431 /** 432 * Returns an array of {@code Class} objects associated with the parameter 433 * types of this method. If the method was declared with no parameters, an 434 * empty array will be returned. 435 * 436 * @return the parameter types 437 */ 438 public Class<?>[] getParameterTypes() { 439 return parameterTypes.clone(); 440 } 441 442 /** 443 * Returns the {@code Class} associated with the return type of this 444 * method. 445 * 446 * @return the return type 447 */ 448 public Class<?> getReturnType() { 449 return returnType; 450 } 451 452 /** 453 * Returns an integer hash code for this method. Objects which are equal 454 * return the same value for this method. The hash code for this Method is 455 * the hash code of the name of this method. 456 * 457 * @return hash code for this method 458 * 459 * @see #equals 460 */ 461 @Override 462 public int hashCode() { 463 return name.hashCode(); 464 } 465 466 /** 467 * Returns the result of dynamically invoking this method. Equivalent to 468 * {@code receiver.methodName(arg1, arg2, ... , argN)}. 469 * 470 * <p>If the method is static, the receiver argument is ignored (and may be null). 471 * 472 * <p>If the method takes no arguments, you can pass {@code (Object[]) null} instead of 473 * allocating an empty array. 474 * 475 * <p>If you're calling a varargs method, you need to pass an {@code Object[]} for the 476 * varargs parameter: that conversion is usually done in {@code javac}, not the VM, and 477 * the reflection machinery does not do this for you. (It couldn't, because it would be 478 * ambiguous.) 479 * 480 * <p>Reflective method invocation follows the usual process for method lookup. 481 * 482 * <p>If an exception is thrown during the invocation it is caught and 483 * wrapped in an InvocationTargetException. This exception is then thrown. 484 * 485 * <p>If the invocation completes normally, the return value itself is 486 * returned. If the method is declared to return a primitive type, the 487 * return value is boxed. If the return type is void, null is returned. 488 * 489 * @param receiver 490 * the object on which to call this method (or null for static methods) 491 * @param args 492 * the arguments to the method 493 * @return the result 494 * 495 * @throws NullPointerException 496 * if {@code receiver == null} for a non-static method 497 * @throws IllegalAccessException 498 * if this method is not accessible (see {@link AccessibleObject}) 499 * @throws IllegalArgumentException 500 * if the number of arguments doesn't match the number of parameters, the receiver 501 * is incompatible with the declaring class, or an argument could not be unboxed 502 * or converted by a widening conversion to the corresponding parameter type 503 * @throws InvocationTargetException 504 * if an exception was thrown by the invoked method 505 */ 506 public Object invoke(Object receiver, Object... args) 507 throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 508 if (args == null) { 509 args = EmptyArray.OBJECT; 510 } 511 return invokeNative(receiver, args, declaringClass, parameterTypes, returnType, slot, flag); 512 } 513 514 private native Object invokeNative(Object obj, Object[] args, Class<?> declaringClass, 515 Class<?>[] parameterTypes, Class<?> returnType, int slot, boolean noAccessCheck) 516 throws IllegalAccessException, IllegalArgumentException, 517 InvocationTargetException; 518 519 /** 520 * Returns a string containing a concise, human-readable description of this 521 * method. The format of the string is: 522 * 523 * <ol> 524 * <li>modifiers (if any) 525 * <li>return type or 'void' 526 * <li>declaring class name 527 * <li>'(' 528 * <li>parameter types, separated by ',' (if any) 529 * <li>')' 530 * <li>'throws' plus exception types, separated by ',' (if any) 531 * </ol> 532 * 533 * For example: {@code public native Object 534 * java.lang.Method.invoke(Object,Object) throws 535 * IllegalAccessException,IllegalArgumentException 536 * ,InvocationTargetException} 537 * 538 * @return a printable representation for this method 539 */ 540 @Override 541 public String toString() { 542 StringBuilder result = new StringBuilder(Modifier.toString(getModifiers())); 543 544 if (result.length() != 0) 545 result.append(' '); 546 result.append(returnType.getName()); 547 result.append(' '); 548 result.append(declaringClass.getName()); 549 result.append('.'); 550 result.append(name); 551 result.append("("); 552 result.append(toString(parameterTypes)); 553 result.append(")"); 554 if (exceptionTypes != null && exceptionTypes.length != 0) { 555 result.append(" throws "); 556 result.append(toString(exceptionTypes)); 557 } 558 559 return result.toString(); 560 } 561 562 /** 563 * Returns the constructor's signature in non-printable form. This is called 564 * (only) from IO native code and needed for deriving the serialVersionUID 565 * of the class 566 * 567 * @return The constructor's signature. 568 */ 569 @SuppressWarnings("unused") 570 private String getSignature() { 571 StringBuilder result = new StringBuilder(); 572 573 result.append('('); 574 for (int i = 0; i < parameterTypes.length; i++) { 575 result.append(getSignature(parameterTypes[i])); 576 } 577 result.append(')'); 578 result.append(getSignature(returnType)); 579 580 return result.toString(); 581 } 582 583 }
Modifier編程
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.lang.reflect; 19 20 /** 21 * This class provides static methods to decode class and member modifiers. 22 * 23 * @see Class#getModifiers() 24 * @see Member#getModifiers() 25 */ 26 public class Modifier { 27 28 /** 29 * The {@code int} value representing the {@code public} 30 * modifier. 31 */ 32 public static final int PUBLIC = 0x1; 33 34 /** 35 * The {@code int} value representing the {@code private} 36 * modifier. 37 */ 38 public static final int PRIVATE = 0x2; 39 40 /** 41 * The {@code int} value representing the {@code protected} 42 * modifier. 43 */ 44 public static final int PROTECTED = 0x4; 45 46 /** 47 * The {@code int} value representing the {@code static} modifier. 48 */ 49 public static final int STATIC = 0x8; 50 51 /** 52 * The {@code int} value representing the {@code final} modifier. 53 */ 54 public static final int FINAL = 0x10; 55 56 /** 57 * The {@code int} value representing the {@code synchronized} 58 * modifier. 59 */ 60 public static final int SYNCHRONIZED = 0x20; 61 62 /** 63 * The {@code int} value representing the {@code volatile} 64 * modifier. 65 */ 66 public static final int VOLATILE = 0x40; 67 68 /** 69 * The {@code int} value representing the {@code transient} 70 * modifier. 71 */ 72 public static final int TRANSIENT = 0x80; 73 74 /** 75 * The {@code int} value representing the {@code native} modifier. 76 */ 77 public static final int NATIVE = 0x100; 78 79 /** 80 * The {@code int} value representing the {@code interface} 81 * modifier. 82 */ 83 public static final int INTERFACE = 0x200; 84 85 /** 86 * The {@code int} value representing the {@code abstract} 87 * modifier. 88 */ 89 public static final int ABSTRACT = 0x400; 90 91 /** 92 * The {@code int} value representing the {@code strict} modifier. 93 */ 94 public static final int STRICT = 0x800; 95 96 // Non-public types required by Java 5 update to class file format 97 static final int BRIDGE = 0x40; 98 99 static final int VARARGS = 0x80; 100 101 static final int SYNTHETIC = 0x1000; 102 103 static final int ANNOTATION = 0x2000; 104 105 static final int ENUM = 0x4000; 106 107 /** 108 * Constructs a new {@code Modifier} instance. 109 */ 110 public Modifier() { 111 } 112 113 /** 114 * Returns a mask of all the modifiers that may be applied to classes. 115 * @since 1.7 116 * @hide 1.7 117 */ 118 public static int classModifiers() { 119 return PUBLIC | PROTECTED | PRIVATE | ABSTRACT | STATIC | FINAL | STRICT; 120 } 121 122 /** 123 * Returns a mask of all the modifiers that may be applied to constructors. 124 * @since 1.7 125 * @hide 1.7 126 */ 127 public static int constructorModifiers() { 128 return PUBLIC | PROTECTED | PRIVATE; 129 } 130 131 /** 132 * Returns a mask of all the modifiers that may be applied to fields. 133 * @since 1.7 134 * @hide 1.7 135 */ 136 public static int fieldModifiers() { 137 return PUBLIC | PROTECTED | PRIVATE | STATIC | FINAL | TRANSIENT | VOLATILE; 138 } 139 140 /** 141 * Returns a mask of all the modifiers that may be applied to interfaces. 142 * @since 1.7 143 * @hide 1.7 144 */ 145 public static int interfaceModifiers() { 146 return PUBLIC | PROTECTED | PRIVATE | ABSTRACT | STATIC | STRICT; 147 } 148 149 /** 150 * Returns a mask of all the modifiers that may be applied to methods. 151 * @since 1.7 152 * @hide 1.7 153 */ 154 public static int methodModifiers() { 155 return PUBLIC | PROTECTED | PRIVATE | ABSTRACT | STATIC | FINAL | SYNCHRONIZED | NATIVE | STRICT; 156 } 157 158 /** 159 * Indicates whether or not the specified modifiers contain the {@code 160 * abstract} modifier. 161 * 162 * @param modifiers 163 * the modifiers to test 164 * @return {@code true} if the specified modifiers contain the {@code 165 * abstract} modifier, {@code false} otherwise 166 */ 167 public static boolean isAbstract(int modifiers) { 168 return ((modifiers & ABSTRACT) != 0); 169 } 170 171 /** 172 * Indicates whether or not the specified modifiers contain the {@code 173 * final} modifier. 174 * 175 * @param modifiers 176 * the modifiers to test 177 * @return {@code true} if the specified modifiers contain the {@code 178 * final} modifier, {@code false} otherwise 179 */ 180 public static boolean isFinal(int modifiers) { 181 return ((modifiers & FINAL) != 0); 182 } 183 184 /** 185 * Indicates whether or not the specified modifiers contain the {@code 186 * interface} modifier. 187 * 188 * @param modifiers 189 * the modifiers to test 190 * @return {@code true} if the specified modifiers contain the {@code 191 * interface} modifier, {@code false} otherwise 192 */ 193 public static boolean isInterface(int modifiers) { 194 return ((modifiers & INTERFACE) != 0); 195 } 196 197 /** 198 * Indicates whether or not the specified modifiers contain the {@code 199 * native} modifier. 200 * 201 * @param modifiers 202 * the modifiers to test 203 * @return {@code true} if the specified modifiers contain the {@code 204 * native} modifier, {@code false} otherwise 205 */ 206 public static boolean isNative(int modifiers) { 207 return ((modifiers & NATIVE) != 0); 208 } 209 210 /** 211 * Indicates whether or not the specified modifiers contain the {@code 212 * private} modifier. 213 * 214 * @param modifiers 215 * the modifiers to test 216 * @return {@code true} if the specified modifiers contain the {@code 217 * private} modifier, {@code false} otherwise 218 */ 219 public static boolean isPrivate(int modifiers) { 220 return ((modifiers & PRIVATE) != 0); 221 } 222 223 /** 224 * Indicates whether or not the specified modifiers contain the {@code 225 * protected} modifier. 226 * 227 * @param modifiers 228 * the modifiers to test 229 * @return {@code true} if the specified modifiers contain the {@code 230 * protected} modifier, {@code false} otherwise 231 */ 232 public static boolean isProtected(int modifiers) { 233 return ((modifiers & PROTECTED) != 0); 234 } 235 236 /** 237 * Indicates whether or not the specified modifiers contain the {@code 238 * public} modifier. 239 * 240 * @param modifiers 241 * the modifiers to test 242 * @return {@code true} if the specified modifiers contain the {@code 243 * public} modifier, {@code false} otherwise 244 */ 245 public static boolean isPublic(int modifiers) { 246 return ((modifiers & PUBLIC) != 0); 247 } 248 249 /** 250 * Indicates whether or not the specified modifiers contain the {@code 251 * static} modifier. 252 * 253 * @param modifiers 254 * the modifiers to test 255 * @return {@code true} if the specified modifiers contain the {@code 256 * static} modifier, {@code false} otherwise 257 */ 258 public static boolean isStatic(int modifiers) { 259 return ((modifiers & STATIC) != 0); 260 } 261 262 /** 263 * Indicates whether or not the specified modifiers contain the {@code 264 * strict} modifier. 265 * 266 * @param modifiers 267 * the modifiers to test 268 * @return {@code true} if the specified modifiers contain the {@code 269 * strict} modifier, {@code false} otherwise 270 */ 271 public static boolean isStrict(int modifiers) { 272 return ((modifiers & STRICT) != 0); 273 } 274 275 /** 276 * Indicates whether or not the specified modifiers contain the {@code 277 * synchronized} modifier. 278 * 279 * @param modifiers 280 * the modifiers to test 281 * @return {@code true} if the specified modifiers contain the {@code 282 * synchronized} modifier, {@code false} otherwise 283 */ 284 public static boolean isSynchronized(int modifiers) { 285 return ((modifiers & SYNCHRONIZED) != 0); 286 } 287 288 /** 289 * Indicates whether or not the specified modifiers contain the {@code 290 * transient} modifier. 291 * 292 * @param modifiers 293 * the modifiers to test 294 * @return {@code true} if the specified modifiers contain the {@code 295 * transient} modifier, {@code false} otherwise 296 */ 297 public static boolean isTransient(int modifiers) { 298 return ((modifiers & TRANSIENT) != 0); 299 } 300 301 /** 302 * Indicates whether or not the specified modifiers contain the {@code 303 * volatile} modifier. 304 * 305 * @param modifiers 306 * the modifiers to test 307 * @return {@code true} if the specified modifiers contain the {@code 308 * volatile} modifier, {@code false} otherwise 309 */ 310 public static boolean isVolatile(int modifiers) { 311 return ((modifiers & VOLATILE) != 0); 312 } 313 314 /** 315 * Returns a string containing the string representation of all modifiers 316 * present in the specified modifiers. Modifiers appear in the order 317 * specified by the Java Language Specification: 318 * 319 * {@code public private protected abstract static final transient volatile native synchronized interface strict} 320 * 321 * @param modifiers 322 * the modifiers to print 323 * @return a printable representation of the modifiers 324 */ 325 public static java.lang.String toString(int modifiers) { 326 StringBuilder buf = new StringBuilder(); 327 328 if (isPublic(modifiers)) { 329 buf.append("public "); 330 } 331 if (isProtected(modifiers)) { 332 buf.append("protected "); 333 } 334 if (isPrivate(modifiers)) { 335 buf.append("private "); 336 } 337 if (isAbstract(modifiers)) { 338 buf.append("abstract "); 339 } 340 if (isStatic(modifiers)) { 341 buf.append("static "); 342 } 343 if (isFinal(modifiers)) { 344 buf.append("final "); 345 } 346 if (isTransient(modifiers)) { 347 buf.append("transient "); 348 } 349 if (isVolatile(modifiers)) { 350 buf.append("volatile "); 351 } 352 if (isSynchronized(modifiers)) { 353 buf.append("synchronized "); 354 } 355 if (isNative(modifiers)) { 356 buf.append("native "); 357 } 358 if (isStrict(modifiers)) { 359 buf.append("strictfp "); 360 } 361 if (isInterface(modifiers)) { 362 buf.append("interface "); 363 } 364 if (buf.length() == 0) { 365 return ""; 366 } 367 buf.setLength(buf.length() - 1); 368 return buf.toString(); 369 } 370 }