Java Exception & RTTI

Exception

 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("
");
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("	at ");
329                 err.append(stack[i].toString());
330                 err.append("
");
331             }
332 
333             if (duplicates > 0) {
334                 err.append(indent);
335                 err.append("	... ");
336                 err.append(Integer.toString(duplicates));
337                 err.append(" more
");
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("	Suppressed: ");
346                 throwable.printStackTrace(err, indent + "	", 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 }
View Code
 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 }
View Code
  1. Java的基本原理就是“形式错误的代码不会运行”。
  2. 与C++类似,捕获错误最理想的是在编译期间,最好在试图运行程序以前。
  3. “违例条件”表示在出现什么问题的时候应中止方法或作用域的继续。为了将违例条件与普通问题区分开,违例条件是非常重要的一个因素。而在违例条件的情况下,却无法继续下去,因为当地没有提供解决问题所需的足够多的信息。此时,我们能做的唯一事情就是跳出当地环境,将那个问题委托给一个更高级的负责人。这便是出现违例时出现的情况。
  4. 首先,按照与创建Java对象一样的方法创建违例对象:在内存“堆”里,使用new来创建。随后,停止当前执行路径(记住不可沿这条路径继续下去),然后从当前的环境中释放出违例对象的句柄。此时,违例控制机制会接管一切,并开始查找一个恰当的地方,用于继续程序的执行。这个恰当的地方便是“违例控制器”,它的职责是从问题中恢复,使程序要么尝试另一条执行路径,要么简单地继续。
  5. 和Java的其他任何对象一样,需要用new在内存堆里创建违例,并需调用一个构建器。在所有标准违例中,存在着两个构建器:第一个是默认构建器,第二个则需使用一个字串自变量,使我们能在违例里置入相关信息.
  6. 若某个方法产生一个违例,必须保证该违例能被捕获,并获得正确对待。对于Java的违例控制机制,它的一个好处就是允许我们在一个地方将精力集中在要解决的问题上,然后在另一个地方对待来自那个代码内部的错误。
  7. 若位于一个方法内部,并“掷”出一个违例(或在这个方法内部调用的另一个方法产生了违例),那个方法就会在违例产生过程中退出。若不想一个throw离开方法,可在那个方法内部设置一个特殊的代码块,用它捕获违例。这就叫作“try块”,因为要在这个地方“尝试”各种方法调用。try块属于一种普通的作用域,用一个try关键字开头:
    try {// 可能产生违例的代码}
  8. 当然,生成的违例必须在某个地方中止。这个“地方”便是违例控制器或者违例控制模块。而且针对想捕获的每种违例类型,都必须有一个相应的违例控制器。违例控制器紧接在try块后面,且用catch(捕获)关键字标记。
  9. 控制器必须“紧接”在try块后面。若“掷”出一个违例,违例控制机制就会搜寻自变量与违例类型相符的第一个控制器。随后,它会进入那个catch从句,并认为违例已得到控制(一旦catch从句结束,对控制器的搜索也会停止)。只有相符的catch从句才会得到执行;它与switch语句不同,后者在每个case后都需要一个break命令,防止误执行其他语句。在try块内部,请注意大量不同的方法调用可能生成相同的违例,但只需要一个控制器。
  10. 违例规范采用了一个额外的关键字:throws;后面跟随全部潜在的违例类型。
  11. 假若方法造成了一个违例,但没有对其进行控制,编译器会侦测到这个情况,并告诉我们必须控制违例,或者指出应该从方法里“掷”出一个违例规范。通过坚持从顶部到底部排列违例规范,Java可在编译期保证违例的正确性(注释②)。
  12. 我们可创建一个控制器,令其捕获所有类型的违例。具体的做法是捕获基础类违例类型Exception(也存在其他类型的基础违例,但Exception是适用于几乎所有编程活动的基础)。
  13. 在某些情况下,我们想重新掷出刚才产生过的违例,特别是在用Exception捕获所有可能的违例时。由于我们已拥有当前违例的句柄,所以只需简单地重新掷出那个句柄即可. 重新“掷”出一个违例导致违例进入更高一级环境的违例控制器中。用于同一个try块的任何更进一步的catch从句仍然会被忽略。此外,与违例对象有关的所有东西都会得到保留,所以用于捕获特定违例类型的更高一级的控制器可以从那个对象里提取出所有信息。
  14. Throwable类必须在违例规格中出现,因为fillInStackTrace()会生成一个Throwable对象的句柄。由于Throwable是Exception的一个基础类,所以有可能获得一个能够“掷”出的对象(具有Throwable属性),但却并非一个Exception(违例)。因此,在main()中用于Exception的句柄可能丢失自己的目标。为保证所有东西均井然有序,编译器强制Throwable使用一个违例规范。
  15. Java包含了一个名为Throwable的类,它对可以作为违例“掷”出的所有东西进行了描述。Throwable对象有两种常规类型(亦即“从Throwable继承”)。其中,Error代表编译期和系统错误,我们一般不必特意捕获它们(除在特殊情况以外)。Exception是可以从任何标准Java库的类方法中“掷”出的基本类型。此外,它们亦可从我们自己的方法以及运行期偶发事件中“掷”出。
  16. 由于编译器并不强制违例规范捕获它们,所以假如不捕获的话,一个RuntimeException可能过滤掉我们到达main()方法的所有途径。
  17. 假若一个RuntimeException获得到达main()的所有途径,同时不被捕获,那么当程序退出时,会为那个违例调用printStackTrace()。注意也许能在自己的代码中仅忽略RuntimeException,因为编译器已正确实行了其他所有控制。因为RuntimeException在此时代表一个编程错误:(1) 一个我们不能捕获的错误(例如,由客户程序员接收传递给自己方法的一个空句柄)。(2) 作为一名程序员,一个应在自己的代码中检查的错误(如ArrayIndexOutOfBoundException,此时应注意数组的大小)。
  18. 为创建自己的违例类,必须从一个现有的违例类型继承——最好在含义上与新违例近似。在第二个构建器中,通过使用super关键字,明确调用了带有一个String参数的基础类构建器。
  19. 覆盖一个方法时,只能产生已在方法的基础类版本中定义的违例。这是一个重要的限制,因为它意味着与基础类协同工作的代码也会自动应用于从基础类衍生的任何对象(当然,这属于基本的OOP概念),其中包括违例。
  20. C++施加了类似的限制,要求衍生方法违例与基础类方法掷出的违例相同,或者从后者衍生。在这种情况下,C++实际上能够在编译期间检查违例规范。
  21. 尽管违例规范是由编译器在继承期间强行遵守的,但违例规范并不属于方法类型的一部分,后者仅包括了方法名以及自变量类型。因此,我们不可在违例规范的基础上覆盖方法。除此以外,尽管违例规范存在于一个方法的基础类版本中,但并不表示它必须在方法的衍生类版本中存在。这与方法的“继承”颇有不同(进行继承时,基础类中的方法也必须在衍生类中存在)。换言之,用于一个特定方法的“违例规范接口”可能在继承和覆盖时变得更“窄”,但它不会变得更“宽”——这与继承时的类接口规则是正好相反的。
  22. 无论一个违例是否在try块中发生,我们经常都想执行一些特定的代码。对一些特定的操作,经常都会遇到这种情况,但在恢复内存时一般都不需要(因为垃圾收集器会自动照料一切)。为达到这个目的,可在所有违例控制器的末尾使用一个finally从句(注释④)。
  23. 在没有“垃圾收集”以及“自动调用破坏器”机制的一种语言中(注释⑤),finally显得特别重要,因为程序员可用它担保内存的正确释放——无论在try块内部发生了什么状况。但Java提供了垃圾收集机制,所以内存的释放几乎绝对不会成为问题。另外,它也没有构建器可供调用。
  24. “破坏器”(Destructor)是“构建器”(Constructor)的反义词。它代表一个特殊的函数,一旦某个对象失去用处,通常就会调用它。我们肯定知道在哪里以及何时调用破坏器。C++提供了自动的破坏器调用机制,但Delphi的Object Pascal版本1及2却不具备这一能力(在这种语言中,破坏器的含义与用法都发生了变化)。
  25. “掷”出一个违例后,违例控制系统会按当初编写的顺序搜索“最接近”的控制器。一旦找到相符的控制器,就认为违例已得到控制,不再进行更多的搜索工作。在违例和它的控制器之间,并不需要非常精确的匹配。一个衍生类对象可与基础类的一个控制器相配.
  26. 用违例做下面这些事情:
    (1) 解决问题并再次调用造成违例的方法。
    (2) 平息事态的发展,并在不重新尝试方法的前提下继续。
    (3) 计算另一些结果,而不是希望方法产生的结果。
    (4) 在当前环境中尽可能解决问题,以及将相同的违例重新“掷”出一个更高级的环境。
    (5) 在当前环境中尽可能解决问题,以及将不同的违例重新“掷”出一个更高级的环境。
    (6) 中止程序执行。
    (7) 简化编码。若违例方案使事情变得更加复杂,那就会令人非常烦恼,不如不用。
    (8) 使自己的库和程序变得更加安全。这既是一种“短期投资”(便于调试),也是一种“长期投资”(改善应用程序的健壮性)

RTTI = Running-Time Type Identification      

Class

   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 }
View Code

Constructor

  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 }
View Code

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 }
View Code

Member

 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 }
View Code

Method

  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 }
View Code

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 }
View Code
  1. 运行期类型鉴定(RTTI)的概念初看非常简单——手上只有基础类型的一个句柄时,利用它判断一个对象的正确类型。一种是“传统”RTTI,它假定我们已在编译和运行期拥有所有类型;另一种是Java1.1特有的“反射”机制,利用它可在运行期独立查找类信息。
  2. In C++, dynamic_cast and typeid operator works only for class with virtual function. In fact, type_info is inserted in the first slot of vtble, if vtble exist.
  3. 为理解RTTI在Java里如何工作,首先必须了解类型信息在运行期是如何表示的。这时要用到一个名为“Class对象”的特殊形式的对象,其中包含了与类有关的信息(有时也把它叫作“元类”)。事实上,我们要用Class对象创建属于某个类的全部“常规”或“普通”对象。对于作为程序一部分的每个类,它们都有一个Class对象。换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当地说,是保存在一个完全同名的.class文件中)。在运行期,一旦我们想生成那个类的一个对象,用于执行程序的Java虚拟机(JVM)首先就会检查那个类型的Class对象是否已经载入。若尚未载入,JVM就会查找同名的.class文件,并将其载入。所以Java程序启动时并不是完全载入的,这一点与许多传统语言都不同。一旦那个类型的Class对象进入内存,就用它创建那一类型的所有对象。
  4. Class.forName("Gum");
    该方法是Class(即全部Class所从属的)的一个static成员。而Class对象和其他任何对象都是类似的,所以能够获取和控制它的一个句柄(装载模块就是干这件事的)。为获得Class的一个句柄,一个办法是使用forName()。它的作用是取得包含了目标类文本名字的一个String(注意拼写和大小写)。最后返回的是一个Class句柄。
  5. Class.forName("Gum");
    该方法是Class(即全部Class所从属的)的一个static成员。而Class对象和其他任何对象都是类似的,所以能够获取和控制它的一个句柄(装载模块就是干这件事的)。为获得Class的一个句柄,一个办法是使用forName()。它的作用是取得包含了目标类文本名字的一个String(注意拼写和大小写)。最后返回的是一个Class句柄。
  6. RTTI在Java中存在三种形式。关键字instanceof告诉我们对象是不是一个特定类型的实例(Instance即“实例”)。它会返回一个布尔值,以便以问题的形式使用,就象下面这样:if(x instanceof Dog)
  7. 首先必须获得指向适当Class对象的的一个句柄。就象前例演示的那样,一个办法是用一个字串以及Class.forName()方法。这是非常方便的,因为不需要那种类型的一个对象来获取Class句柄。然而,对于自己感兴趣的类型,如果已有了它的一个对象,那么为了取得Class句柄,可调用属于Object根类一部分的一个方法:getClass()。它的作用是返回一个特定的Class句柄,用来表示对象的实际类型。
  8. 若从表面看,Class的newInstance()方法似乎是克隆(clone())一个对象的另一种手段。但两者是有区别的。利用newInstance(),我们可在没有现成对象供“克隆”的情况下新建一个对象。就象上面的程序演示的那样,当时没有Toy对象,只有cy——即y的Class对象的一个句柄。利用它可以实现“虚拟构建器”。换言之,我们表达:“尽管我不知道你的准确类型是什么,但请你无论如何都正确地创建自己。
  9. 如果不知道一个对象的准确类型,RTTI会帮助我们调查。但却有一个限制:类型必须是在编译期间已知的,否则就不能用RTTI调查它,进而无法展开下一步的工作。换言之,编译器必须明确知道RTTI要处理的所有类。
  10. 用“快速应用开发”(RAD)模型来构建程序项目。RAD一般是在应用程序构建工具中内建的。这是编制程序的一种可视途径(在屏幕上以窗体的形式出现)。可将代表不同组件的图标拖曳到窗体中。随后,通过设定这些组件的属性或者值,进行正确的配置。设计期间的配置要求任何组件都是可以“例示”的(即可以自由获得它们的实例)。这些组件也要揭示出自己的一部分内容,允许程序员读取和设置各种值。此外,用于控制GUI事件的组件必须揭示出与相应的方法有关的信息,以便RAD环境帮助程序员用自己的代码覆盖这些由事件驱动的方法。“反射”提供了一种特殊的机制,可以侦测可用的方法,并产生方法名。通过Java Beans(第13章将详细介绍),Java 1.1为这种基于组件的程序设计提供了一个基础结构。
  11. 在运行期查询类信息的另一个原动力是通过网络创建与执行位于远程系统上的对象。这就叫作“远程方法调用”(RMI),它允许Java程序(版本1.1以上)使用由多台机器发布或分布的对象。这种对象的分布可能是由多方面的原因引起的:可能要做一件计算密集型的工作,想对它进行分割,让处于空闲状态的其他机器分担部分工作,从而加快处理进度。某些情况下,可能需要将用于控制特定类型任务(比如多层客户/服务器架构中的“运作规则”)的代码放置在一台特殊的机器上,使这台机器成为对那些行动进行描述的一个通用储藏所。而且可以方便地修改这个场所,使其对系统内的所有方面产生影响(这是一种特别有用的设计思路,因为机器是独立存在的,所以能轻易修改软件!)。分布式计算也能更充分地发挥某些专用硬件的作用,它们特别擅长执行一些特定的任务——例如矩阵逆转——但对常规编程来说却显得太夸张或者太昂贵了。
  12. Class类(本章前面已有详细论述)得到了扩展,可以支持“反射”的概念。针对Field,Method以及Constructor类(每个都实现了Memberinterface——成员接口),它们都新增了一个库:java.lang.reflect。这些类型的对象都是JVM在运行期创建的,用于代表未知类里对应的成员。这样便可用构建器创建新对象,用get()和set()方法读取和修改与Field对象关联的字段,以及用invoke()方法调用与Method对象关联的方法。此外,我们可调用方法getFields(),getMethods(),getConstructors(),分别返回用于表示字段、方法以及构建器的对象数组(在联机文档中,还可找到与Class类有关的更多的资料)。因此,匿名对象的类信息可在运行期被完整的揭露出来,而在编译期间不需要知道任何东西。
  13. 通过“反射”同一个未知类型的对象打交道时,JVM只是简单地检查那个对象,并调查它从属于哪个特定的类(就象以前的RTTI那样)。但在这之后,在我们做其他任何事情之前,Class对象必须载入。因此,用于那种特定类型的.class文件必须能由JVM调用(要么在本地机器内,要么可以通过网络取得)。所以RTTI和“反射”之间唯一的区别就是对RTTI来说,编译器会在编译期打开和检查.class文件。换句话说,我们可以用“普通”方式调用一个对象的所有方法;但对“反射”来说,.class文件在编译期间是不可使用的,而是由运行期环境打开和检查。
  14. Class方法getMethods()和getConstructors()可以分别返回Method和Constructor的一个数组。每个类都提供了进一步的方法,可解析出它们所代表的方法的名字、参数以及返回值。但也可以象这样一样只使用toString(),生成一个含有完整方法签名的字串。
原文地址:https://www.cnblogs.com/iiiDragon/p/3272192.html