Source Code Cross Referenced for Method.java in  » 6.0-JDK-Core » lang » java » lang » reflect » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » lang » java.lang.reflect 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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