History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/lang/reflect/Method.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/lang/reflect/Method.java+767−0
@@ -0,0 +1,767 @@
1+/*
2+ * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.lang.reflect;
27+
28+import sun.reflect.MethodAccessor;
29+import sun.reflect.Reflection;
30+import sun.reflect.generics.repository.MethodRepository;
31+import sun.reflect.generics.factory.CoreReflectionFactory;
32+import sun.reflect.generics.factory.GenericsFactory;
33+import sun.reflect.generics.scope.MethodScope;
34+import sun.reflect.annotation.AnnotationType;
35+import sun.reflect.annotation.AnnotationParser;
36+import java.lang.annotation.Annotation;
37+import java.lang.annotation.AnnotationFormatError;
38+import java.nio.ByteBuffer;
39+import java.util.Map;
40+
41+/**
42+ * A {@code Method} provides information about, and access to, a single method
43+ * on a class or interface. The reflected method may be a class method
44+ * or an instance method (including an abstract method).
45+ *
46+ * <p>A {@code Method} permits widening conversions to occur when matching the
47+ * actual parameters to invoke with the underlying method's formal
48+ * parameters, but it throws an {@code IllegalArgumentException} if a
49+ * narrowing conversion would occur.
50+ *
51+ * @see Member
52+ * @see java.lang.Class
53+ * @see java.lang.Class#getMethods()
54+ * @see java.lang.Class#getMethod(String, Class[])
55+ * @see java.lang.Class#getDeclaredMethods()
56+ * @see java.lang.Class#getDeclaredMethod(String, Class[])
57+ *
58+ * @author Kenneth Russell
59+ * @author Nakul Saraiya
60+ */
61+public final
62+ class Method extends AccessibleObject implements GenericDeclaration,
63+ Member {
64+ private Class<?> clazz;
65+ private int slot;
66+ // This is guaranteed to be interned by the VM in the 1.4
67+ // reflection implementation
68+ private String name;
69+ private Class<?> returnType;
70+ private Class<?>[] parameterTypes;
71+ private Class<?>[] exceptionTypes;
72+ private int modifiers;
73+ // Generics and annotations support
74+ private transient String signature;
75+ // generic info repository; lazily initialized
76+ private transient MethodRepository genericInfo;
77+ private byte[] annotations;
78+ private byte[] parameterAnnotations;
79+ private byte[] annotationDefault;
80+ private volatile MethodAccessor methodAccessor;
81+ // For sharing of MethodAccessors. This branching structure is
82+ // currently only two levels deep (i.e., one root Method and
83+ // potentially many Method objects pointing to it.)
84+ private Method root;
85+
86+ // Generics infrastructure
87+
88+ private String getGenericSignature() {return signature;}
89+
90+ // Accessor for factory
91+ private GenericsFactory getFactory() {
92+ // create scope and factory
93+ return CoreReflectionFactory.make(this, MethodScope.make(this));
94+ }
95+
96+ // Accessor for generic info repository
97+ private MethodRepository getGenericInfo() {
98+ // lazily initialize repository if necessary
99+ if (genericInfo == null) {
100+ // create and cache generic info repository
101+ genericInfo = MethodRepository.make(getGenericSignature(),
102+ getFactory());
103+ }
104+ return genericInfo; //return cached repository
105+ }
106+
107+ /**
108+ * Package-private constructor used by ReflectAccess to enable
109+ * instantiation of these objects in Java code from the java.lang
110+ * package via sun.reflect.LangReflectAccess.
111+ */
112+ Method(Class<?> declaringClass,
113+ String name,
114+ Class<?>[] parameterTypes,
115+ Class<?> returnType,
116+ Class<?>[] checkedExceptions,
117+ int modifiers,
118+ int slot,
119+ String signature,
120+ byte[] annotations,
121+ byte[] parameterAnnotations,
122+ byte[] annotationDefault)
123+ {
124+ this.clazz = declaringClass;
125+ this.name = name;
126+ this.parameterTypes = parameterTypes;
127+ this.returnType = returnType;
128+ this.exceptionTypes = checkedExceptions;
129+ this.modifiers = modifiers;
130+ this.slot = slot;
131+ this.signature = signature;
132+ this.annotations = annotations;
133+ this.parameterAnnotations = parameterAnnotations;
134+ this.annotationDefault = annotationDefault;
135+ }
136+
137+ /**
138+ * Package-private routine (exposed to java.lang.Class via
139+ * ReflectAccess) which returns a copy of this Method. The copy's
140+ * "root" field points to this Method.
141+ */
142+ Method copy() {
143+ // This routine enables sharing of MethodAccessor objects
144+ // among Method objects which refer to the same underlying
145+ // method in the VM. (All of this contortion is only necessary
146+ // because of the "accessibility" bit in AccessibleObject,
147+ // which implicitly requires that new java.lang.reflect
148+ // objects be fabricated for each reflective call on Class
149+ // objects.)
150+ Method res = new Method(clazz, name, parameterTypes, returnType,
151+ exceptionTypes, modifiers, slot, signature,
152+ annotations, parameterAnnotations, annotationDefault);
153+ res.root = this;
154+ // Might as well eagerly propagate this if already present
155+ res.methodAccessor = methodAccessor;
156+ return res;
157+ }
158+
159+ /**
160+ * Returns the {@code Class} object representing the class or interface
161+ * that declares the method represented by this {@code Method} object.
162+ */
163+ public Class<?> getDeclaringClass() {
164+ return clazz;
165+ }
166+
167+ /**
168+ * Returns the name of the method represented by this {@code Method}
169+ * object, as a {@code String}.
170+ */
171+ public String getName() {
172+ return name;
173+ }
174+
175+ /**
176+ * Returns the Java language modifiers for the method represented
177+ * by this {@code Method} object, as an integer. The {@code Modifier} class should
178+ * be used to decode the modifiers.
179+ *
180+ * @see Modifier
181+ */
182+ public int getModifiers() {
183+ return modifiers;
184+ }
185+
186+ /**
187+ * Returns an array of {@code TypeVariable} objects that represent the
188+ * type variables declared by the generic declaration represented by this
189+ * {@code GenericDeclaration} object, in declaration order. Returns an
190+ * array of length 0 if the underlying generic declaration declares no type
191+ * variables.
192+ *
193+ * @return an array of {@code TypeVariable} objects that represent
194+ * the type variables declared by this generic declaration
195+ * @throws GenericSignatureFormatError if the generic
196+ * signature of this generic declaration does not conform to
197+ * the format specified in
198+ * <cite>The Java&trade; Virtual Machine Specification</cite>
199+ * @since 1.5
200+ */
201+ public TypeVariable<Method>[] getTypeParameters() {
202+ if (getGenericSignature() != null)
203+ return (TypeVariable<Method>[])getGenericInfo().getTypeParameters();
204+ else
205+ return (TypeVariable<Method>[])new TypeVariable[0];
206+ }
207+
208+ /**
209+ * Returns a {@code Class} object that represents the formal return type
210+ * of the method represented by this {@code Method} object.
211+ *
212+ * @return the return type for the method this object represents
213+ */
214+ public Class<?> getReturnType() {
215+ return returnType;
216+ }
217+
218+ /**
219+ * Returns a {@code Type} object that represents the formal return
220+ * type of the method represented by this {@code Method} object.
221+ *
222+ * <p>If the return type is a parameterized type,
223+ * the {@code Type} object returned must accurately reflect
224+ * the actual type parameters used in the source code.
225+ *
226+ * <p>If the return type is a type variable or a parameterized type, it
227+ * is created. Otherwise, it is resolved.
228+ *
229+ * @return a {@code Type} object that represents the formal return
230+ * type of the underlying method
231+ * @throws GenericSignatureFormatError
232+ * if the generic method signature does not conform to the format
233+ * specified in
234+ * <cite>The Java&trade; Virtual Machine Specification</cite>
235+ * @throws TypeNotPresentException if the underlying method's
236+ * return type refers to a non-existent type declaration
237+ * @throws MalformedParameterizedTypeException if the
238+ * underlying method's return typed refers to a parameterized
239+ * type that cannot be instantiated for any reason
240+ * @since 1.5
241+ */
242+ public Type getGenericReturnType() {
243+ if (getGenericSignature() != null) {
244+ return getGenericInfo().getReturnType();
245+ } else { return getReturnType();}
246+ }
247+
248+
249+ /**
250+ * Returns an array of {@code Class} objects that represent the formal
251+ * parameter types, in declaration order, of the method
252+ * represented by this {@code Method} object. Returns an array of length
253+ * 0 if the underlying method takes no parameters.
254+ *
255+ * @return the parameter types for the method this object
256+ * represents
257+ */
258+ public Class<?>[] getParameterTypes() {
259+ return (Class<?>[]) parameterTypes.clone();
260+ }
261+
262+ /**
263+ * Returns an array of {@code Type} objects that represent the formal
264+ * parameter types, in declaration order, of the method represented by
265+ * this {@code Method} object. Returns an array of length 0 if the
266+ * underlying method takes no parameters.
267+ *
268+ * <p>If a formal parameter type is a parameterized type,
269+ * the {@code Type} object returned for it must accurately reflect
270+ * the actual type parameters used in the source code.
271+ *
272+ * <p>If a formal parameter type is a type variable or a parameterized
273+ * type, it is created. Otherwise, it is resolved.
274+ *
275+ * @return an array of Types that represent the formal
276+ * parameter types of the underlying method, in declaration order
277+ * @throws GenericSignatureFormatError
278+ * if the generic method signature does not conform to the format
279+ * specified in
280+ * <cite>The Java&trade; Virtual Machine Specification</cite>
281+ * @throws TypeNotPresentException if any of the parameter
282+ * types of the underlying method refers to a non-existent type
283+ * declaration
284+ * @throws MalformedParameterizedTypeException if any of
285+ * the underlying method's parameter types refer to a parameterized
286+ * type that cannot be instantiated for any reason
287+ * @since 1.5
288+ */
289+ public Type[] getGenericParameterTypes() {
290+ if (getGenericSignature() != null)
291+ return getGenericInfo().getParameterTypes();
292+ else
293+ return getParameterTypes();
294+ }
295+
296+
297+ /**
298+ * Returns an array of {@code Class} objects that represent
299+ * the types of the exceptions declared to be thrown
300+ * by the underlying method
301+ * represented by this {@code Method} object. Returns an array of length
302+ * 0 if the method declares no exceptions in its {@code throws} clause.
303+ *
304+ * @return the exception types declared as being thrown by the
305+ * method this object represents
306+ */
307+ public Class<?>[] getExceptionTypes() {
308+ return (Class<?>[]) exceptionTypes.clone();
309+ }
310+
311+ /**
312+ * Returns an array of {@code Type} objects that represent the
313+ * exceptions declared to be thrown by this {@code Method} object.
314+ * Returns an array of length 0 if the underlying method declares
315+ * no exceptions in its {@code throws} clause.
316+ *
317+ * <p>If an exception type is a type variable or a parameterized
318+ * type, it is created. Otherwise, it is resolved.
319+ *
320+ * @return an array of Types that represent the exception types
321+ * thrown by the underlying method
322+ * @throws GenericSignatureFormatError
323+ * if the generic method signature does not conform to the format
324+ * specified in
325+ * <cite>The Java&trade; Virtual Machine Specification</cite>
326+ * @throws TypeNotPresentException if the underlying method's
327+ * {@code throws} clause refers to a non-existent type declaration
328+ * @throws MalformedParameterizedTypeException if
329+ * the underlying method's {@code throws} clause refers to a
330+ * parameterized type that cannot be instantiated for any reason
331+ * @since 1.5
332+ */
333+ public Type[] getGenericExceptionTypes() {
334+ Type[] result;
335+ if (getGenericSignature() != null &&
336+ ((result = getGenericInfo().getExceptionTypes()).length > 0))
337+ return result;
338+ else
339+ return getExceptionTypes();
340+ }
341+
342+ /**
343+ * Compares this {@code Method} against the specified object. Returns
344+ * true if the objects are the same. Two {@code Methods} are the same if
345+ * they were declared by the same class and have the same name
346+ * and formal parameter types and return type.
347+ */
348+ public boolean equals(Object obj) {
349+ if (obj != null && obj instanceof Method) {
350+ Method other = (Method)obj;
351+ if ((getDeclaringClass() == other.getDeclaringClass())
352+ && (getName() == other.getName())) {
353+ if (!returnType.equals(other.getReturnType()))
354+ return false;
355+ /* Avoid unnecessary cloning */
356+ Class<?>[] params1 = parameterTypes;
357+ Class<?>[] params2 = other.parameterTypes;
358+ if (params1.length == params2.length) {
359+ for (int i = 0; i < params1.length; i++) {
360+ if (params1[i] != params2[i])
361+ return false;
362+ }
363+ return true;
364+ }
365+ }
366+ }
367+ return false;
368+ }
369+
370+ /**
371+ * Returns a hashcode for this {@code Method}. The hashcode is computed
372+ * as the exclusive-or of the hashcodes for the underlying
373+ * method's declaring class name and the method's name.
374+ */
375+ public int hashCode() {
376+ return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
377+ }
378+
379+ /**
380+ * Returns a string describing this {@code Method}. The string is
381+ * formatted as the method access modifiers, if any, followed by
382+ * the method return type, followed by a space, followed by the
383+ * class declaring the method, followed by a period, followed by
384+ * the method name, followed by a parenthesized, comma-separated
385+ * list of the method's formal parameter types. If the method
386+ * throws checked exceptions, the parameter list is followed by a
387+ * space, followed by the word throws followed by a
388+ * comma-separated list of the thrown exception types.
389+ * For example:
390+ * <pre>
391+ * public boolean java.lang.Object.equals(java.lang.Object)
392+ * </pre>
393+ *
394+ * <p>The access modifiers are placed in canonical order as
395+ * specified by "The Java Language Specification". This is
396+ * {@code public}, {@code protected} or {@code private} first,
397+ * and then other modifiers in the following order:
398+ * {@code abstract}, {@code static}, {@code final},
399+ * {@code synchronized}, {@code native}, {@code strictfp}.
400+ */
401+ public String toString() {
402+ try {
403+ StringBuilder sb = new StringBuilder();
404+ int mod = getModifiers() & Modifier.methodModifiers();
405+ if (mod != 0) {
406+ sb.append(Modifier.toString(mod)).append(' ');
407+ }
408+ sb.append(Field.getTypeName(getReturnType())).append(' ');
409+ sb.append(Field.getTypeName(getDeclaringClass())).append('.');
410+ sb.append(getName()).append('(');
411+ Class<?>[] params = parameterTypes; // avoid clone
412+ for (int j = 0; j < params.length; j++) {
413+ sb.append(Field.getTypeName(params[j]));
414+ if (j < (params.length - 1))
415+ sb.append(',');
416+ }
417+ sb.append(')');
418+ Class<?>[] exceptions = exceptionTypes; // avoid clone
419+ if (exceptions.length > 0) {
420+ sb.append(" throws ");
421+ for (int k = 0; k < exceptions.length; k++) {
422+ sb.append(exceptions[k].getName());
423+ if (k < (exceptions.length - 1))
424+ sb.append(',');
425+ }
426+ }
427+ return sb.toString();
428+ } catch (Exception e) {
429+ return "<" + e + ">";
430+ }
431+ }
432+
433+ /**
434+ * Returns a string describing this {@code Method}, including
435+ * type parameters. The string is formatted as the method access
436+ * modifiers, if any, followed by an angle-bracketed
437+ * comma-separated list of the method's type parameters, if any,
438+ * followed by the method's generic return type, followed by a
439+ * space, followed by the class declaring the method, followed by
440+ * a period, followed by the method name, followed by a
441+ * parenthesized, comma-separated list of the method's generic
442+ * formal parameter types.
443+ *
444+ * If this method was declared to take a variable number of
445+ * arguments, instead of denoting the last parameter as
446+ * "<tt><i>Type</i>[]</tt>", it is denoted as
447+ * "<tt><i>Type</i>...</tt>".
448+ *
449+ * A space is used to separate access modifiers from one another
450+ * and from the type parameters or return type. If there are no
451+ * type parameters, the type parameter list is elided; if the type
452+ * parameter list is present, a space separates the list from the
453+ * class name. If the method is declared to throw exceptions, the
454+ * parameter list is followed by a space, followed by the word
455+ * throws followed by a comma-separated list of the generic thrown
456+ * exception types. If there are no type parameters, the type
457+ * parameter list is elided.
458+ *
459+ * <p>The access modifiers are placed in canonical order as
460+ * specified by "The Java Language Specification". This is
461+ * {@code public}, {@code protected} or {@code private} first,
462+ * and then other modifiers in the following order:
463+ * {@code abstract}, {@code static}, {@code final},
464+ * {@code synchronized}, {@code native}, {@code strictfp}.
465+ *
466+ * @return a string describing this {@code Method},
467+ * include type parameters
468+ *
469+ * @since 1.5
470+ */
471+ public String toGenericString() {
472+ try {
473+ StringBuilder sb = new StringBuilder();
474+ int mod = getModifiers() & Modifier.methodModifiers();
475+ if (mod != 0) {
476+ sb.append(Modifier.toString(mod)).append(' ');
477+ }
478+ TypeVariable<?>[] typeparms = getTypeParameters();
479+ if (typeparms.length > 0) {
480+ boolean first = true;
481+ sb.append('<');
482+ for(TypeVariable<?> typeparm: typeparms) {
483+ if (!first)
484+ sb.append(',');
485+ // Class objects can't occur here; no need to test
486+ // and call Class.getName().
487+ sb.append(typeparm.toString());
488+ first = false;
489+ }
490+ sb.append("> ");
491+ }
492+
493+ Type genRetType = getGenericReturnType();
494+ sb.append( ((genRetType instanceof Class<?>)?
495+ Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
496+ .append(' ');
497+
498+ sb.append(Field.getTypeName(getDeclaringClass())).append('.');
499+ sb.append(getName()).append('(');
500+ Type[] params = getGenericParameterTypes();
501+ for (int j = 0; j < params.length; j++) {
502+ String param = (params[j] instanceof Class)?
503+ Field.getTypeName((Class)params[j]):
504+ (params[j].toString());
505+ if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
506+ param = param.replaceFirst("\\[\\]$", "...");
507+ sb.append(param);
508+ if (j < (params.length - 1))
509+ sb.append(',');
510+ }
511+ sb.append(')');
512+ Type[] exceptions = getGenericExceptionTypes();
513+ if (exceptions.length > 0) {
514+ sb.append(" throws ");
515+ for (int k = 0; k < exceptions.length; k++) {
516+ sb.append((exceptions[k] instanceof Class)?
517+ ((Class)exceptions[k]).getName():
518+ exceptions[k].toString());
519+ if (k < (exceptions.length - 1))
520+ sb.append(',');
521+ }
522+ }
523+ return sb.toString();
524+ } catch (Exception e) {
525+ return "<" + e + ">";
526+ }
527+ }
528+
529+ /**
530+ * Invokes the underlying method represented by this {@code Method}
531+ * object, on the specified object with the specified parameters.
532+ * Individual parameters are automatically unwrapped to match
533+ * primitive formal parameters, and both primitive and reference
534+ * parameters are subject to method invocation conversions as
535+ * necessary.
536+ *
537+ * <p>If the underlying method is static, then the specified {@code obj}
538+ * argument is ignored. It may be null.
539+ *
540+ * <p>If the number of formal parameters required by the underlying method is
541+ * 0, the supplied {@code args} array may be of length 0 or null.
542+ *
543+ * <p>If the underlying method is an instance method, it is invoked
544+ * using dynamic method lookup as documented in The Java Language
545+ * Specification, Second Edition, section 15.12.4.4; in particular,
546+ * overriding based on the runtime type of the target object will occur.
547+ *
548+ * <p>If the underlying method is static, the class that declared
549+ * the method is initialized if it has not already been initialized.
550+ *
551+ * <p>If the method completes normally, the value it returns is
552+ * returned to the caller of invoke; if the value has a primitive
553+ * type, it is first appropriately wrapped in an object. However,
554+ * if the value has the type of an array of a primitive type, the
555+ * elements of the array are <i>not</i> wrapped in objects; in
556+ * other words, an array of primitive type is returned. If the
557+ * underlying method return type is void, the invocation returns
558+ * null.
559+ *
560+ * @param obj the object the underlying method is invoked from
561+ * @param args the arguments used for the method call
562+ * @return the result of dispatching the method represented by
563+ * this object on {@code obj} with parameters
564+ * {@code args}
565+ *
566+ * @exception IllegalAccessException if this {@code Method} object
567+ * is enforcing Java language access control and the underlying
568+ * method is inaccessible.
569+ * @exception IllegalArgumentException if the method is an
570+ * instance method and the specified object argument
571+ * is not an instance of the class or interface
572+ * declaring the underlying method (or of a subclass
573+ * or implementor thereof); if the number of actual
574+ * and formal parameters differ; if an unwrapping
575+ * conversion for primitive arguments fails; or if,
576+ * after possible unwrapping, a parameter value
577+ * cannot be converted to the corresponding formal
578+ * parameter type by a method invocation conversion.
579+ * @exception InvocationTargetException if the underlying method
580+ * throws an exception.
581+ * @exception NullPointerException if the specified object is null
582+ * and the method is an instance method.
583+ * @exception ExceptionInInitializerError if the initialization
584+ * provoked by this method fails.
585+ */
586+ public Object invoke(Object obj, Object... args)
587+ throws IllegalAccessException, IllegalArgumentException,
588+ InvocationTargetException
589+ {
590+ if (!override) {
591+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
592+ Class<?> caller = Reflection.getCallerClass(1);
593+
594+ checkAccess(caller, clazz, obj, modifiers);
595+ }
596+ }
597+ MethodAccessor ma = methodAccessor; // read volatile
598+ if (ma == null) {
599+ ma = acquireMethodAccessor();
600+ }
601+ return ma.invoke(obj, args);
602+ }
603+
604+ /**
605+ * Returns {@code true} if this method is a bridge
606+ * method; returns {@code false} otherwise.
607+ *
608+ * @return true if and only if this method is a bridge
609+ * method as defined by the Java Language Specification.
610+ * @since 1.5
611+ */
612+ public boolean isBridge() {
613+ return (getModifiers() & Modifier.BRIDGE) != 0;
614+ }
615+
616+ /**
617+ * Returns {@code true} if this method was declared to take
618+ * a variable number of arguments; returns {@code false}
619+ * otherwise.
620+ *
621+ * @return {@code true} if an only if this method was declared to
622+ * take a variable number of arguments.
623+ * @since 1.5
624+ */
625+ public boolean isVarArgs() {
626+ return (getModifiers() & Modifier.VARARGS) != 0;
627+ }
628+
629+ /**
630+ * Returns {@code true} if this method is a synthetic
631+ * method; returns {@code false} otherwise.
632+ *
633+ * @return true if and only if this method is a synthetic
634+ * method as defined by the Java Language Specification.
635+ * @since 1.5
636+ */
637+ public boolean isSynthetic() {
638+ return Modifier.isSynthetic(getModifiers());
639+ }
640+
641+ // NOTE that there is no synchronization used here. It is correct
642+ // (though not efficient) to generate more than one MethodAccessor
643+ // for a given Method. However, avoiding synchronization will
644+ // probably make the implementation more scalable.
645+ private MethodAccessor acquireMethodAccessor() {
646+ // First check to see if one has been created yet, and take it
647+ // if so
648+ MethodAccessor tmp = null;
649+ if (root != null) tmp = root.getMethodAccessor();
650+ if (tmp != null) {
651+ methodAccessor = tmp;
652+ } else {
653+ // Otherwise fabricate one and propagate it up to the root
654+ tmp = reflectionFactory.newMethodAccessor(this);
655+ setMethodAccessor(tmp);
656+ }
657+
658+ return tmp;
659+ }
660+
661+ // Returns MethodAccessor for this Method object, not looking up
662+ // the chain to the root
663+ MethodAccessor getMethodAccessor() {
664+ return methodAccessor;
665+ }
666+
667+ // Sets the MethodAccessor for this Method object and
668+ // (recursively) its root
669+ void setMethodAccessor(MethodAccessor accessor) {
670+ methodAccessor = accessor;
671+ // Propagate up
672+ if (root != null) {
673+ root.setMethodAccessor(accessor);
674+ }
675+ }
676+
677+ /**
678+ * @throws NullPointerException {@inheritDoc}
679+ * @since 1.5
680+ */
681+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
682+ if (annotationClass == null)
683+ throw new NullPointerException();
684+
685+ return (T) declaredAnnotations().get(annotationClass);
686+ }
687+
688+ /**
689+ * @since 1.5
690+ */
691+ public Annotation[] getDeclaredAnnotations() {
692+ return AnnotationParser.toArray(declaredAnnotations());
693+ }
694+
695+ private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
696+
697+ private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
698+ if (declaredAnnotations == null) {
699+ declaredAnnotations = AnnotationParser.parseAnnotations(
700+ annotations, sun.misc.SharedSecrets.getJavaLangAccess().
701+ getConstantPool(getDeclaringClass()),
702+ getDeclaringClass());
703+ }
704+ return declaredAnnotations;
705+ }
706+
707+ /**
708+ * Returns the default value for the annotation member represented by
709+ * this {@code Method} instance. If the member is of a primitive type,
710+ * an instance of the corresponding wrapper type is returned. Returns
711+ * null if no default is associated with the member, or if the method
712+ * instance does not represent a declared member of an annotation type.
713+ *
714+ * @return the default value for the annotation member represented
715+ * by this {@code Method} instance.
716+ * @throws TypeNotPresentException if the annotation is of type
717+ * {@link Class} and no definition can be found for the
718+ * default class value.
719+ * @since 1.5
720+ */
721+ public Object getDefaultValue() {
722+ if (annotationDefault == null)
723+ return null;
724+ Class<?> memberType = AnnotationType.invocationHandlerReturnType(
725+ getReturnType());
726+ Object result = AnnotationParser.parseMemberValue(
727+ memberType, ByteBuffer.wrap(annotationDefault),
728+ sun.misc.SharedSecrets.getJavaLangAccess().
729+ getConstantPool(getDeclaringClass()),
730+ getDeclaringClass());
731+ if (result instanceof sun.reflect.annotation.ExceptionProxy)
732+ throw new AnnotationFormatError("Invalid default: " + this);
733+ return result;
734+ }
735+
736+ /**
737+ * Returns an array of arrays that represent the annotations on the formal
738+ * parameters, in declaration order, of the method represented by
739+ * this {@code Method} object. (Returns an array of length zero if the
740+ * underlying method is parameterless. If the method has one or more
741+ * parameters, a nested array of length zero is returned for each parameter
742+ * with no annotations.) The annotation objects contained in the returned
743+ * arrays are serializable. The caller of this method is free to modify
744+ * the returned arrays; it will have no effect on the arrays returned to
745+ * other callers.
746+ *
747+ * @return an array of arrays that represent the annotations on the formal
748+ * parameters, in declaration order, of the method represented by this
749+ * Method object
750+ * @since 1.5
751+ */
752+ public Annotation[][] getParameterAnnotations() {
753+ int numParameters = parameterTypes.length;
754+ if (parameterAnnotations == null)
755+ return new Annotation[numParameters][0];
756+
757+ Annotation[][] result = AnnotationParser.parseParameterAnnotations(
758+ parameterAnnotations,
759+ sun.misc.SharedSecrets.getJavaLangAccess().
760+ getConstantPool(getDeclaringClass()),
761+ getDeclaringClass());
762+ if (result.length != numParameters)
763+ throw new java.lang.annotation.AnnotationFormatError(
764+ "Parameter annotations don't match number of parameters");
765+ return result;
766+ }
767+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t