Methodpublic final class Method extends AccessibleObject implements GenericDeclaration, MemberA Method provides information about, and access to, a single method
on a class or interface. The reflected method may be a class method
or an instance method (including an abstract method).
A Method permits widening conversions to occur when matching the
actual parameters to invoke with the underlying method's formal
parameters, but it throws an IllegalArgumentException if a
narrowing conversion would occur. |
Fields Summary |
---|
private Class | clazz | private int | slot | private String | name | private Class | returnType | private Class[] | parameterTypes | private Class[] | exceptionTypes | private int | modifiers | private transient String | signature | private transient MethodRepository | genericInfo | private byte[] | annotations | private byte[] | parameterAnnotations | private byte[] | annotationDefault | private volatile sun.reflect.MethodAccessor | methodAccessor | private Method | root | private Class | securityCheckCache | private Class | securityCheckTargetClassCache | private static final int | LANGUAGE_MODIFIERS | private static final Annotation[] | EMPTY_ANNOTATION_ARRAY | private transient Map | declaredAnnotations |
Constructors Summary |
---|
Method(Class declaringClass, String name, Class[] parameterTypes, Class returnType, Class[] checkedExceptions, int modifiers, int slot, String signature, byte[] annotations, byte[] parameterAnnotations, byte[] annotationDefault)Package-private constructor used by ReflectAccess to enable
instantiation of these objects in Java code from the java.lang
package via sun.reflect.LangReflectAccess.
this.clazz = declaringClass;
this.name = name;
this.parameterTypes = parameterTypes;
this.returnType = returnType;
this.exceptionTypes = checkedExceptions;
this.modifiers = modifiers;
this.slot = slot;
this.signature = signature;
this.annotations = annotations;
this.parameterAnnotations = parameterAnnotations;
this.annotationDefault = annotationDefault;
|
Methods Summary |
---|
private void | acquireMethodAccessor()
// First check to see if one has been created yet, and take it
// if so
MethodAccessor tmp = null;
if (root != null) tmp = root.getMethodAccessor();
if (tmp != null) {
methodAccessor = tmp;
return;
}
// Otherwise fabricate one and propagate it up to the root
tmp = reflectionFactory.newMethodAccessor(this);
setMethodAccessor(tmp);
| java.lang.reflect.Method | copy()Package-private routine (exposed to java.lang.Class via
ReflectAccess) which returns a copy of this Method. The copy's
"root" field points to this Method.
// This routine enables sharing of MethodAccessor objects
// among Method objects which refer to the same underlying
// method in the VM. (All of this contortion is only necessary
// because of the "accessibility" bit in AccessibleObject,
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects.)
Method res = new Method(clazz, name, parameterTypes, returnType,
exceptionTypes, modifiers, slot, signature,
annotations, parameterAnnotations, annotationDefault);
res.root = this;
// Might as well eagerly propagate this if already present
res.methodAccessor = methodAccessor;
return res;
| private synchronized java.util.Map | declaredAnnotations()
if (declaredAnnotations == null) {
declaredAnnotations = AnnotationParser.parseAnnotations(
annotations, sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
getDeclaringClass());
}
return declaredAnnotations;
| public boolean | equals(java.lang.Object obj)Compares this Method against the specified object. Returns
true if the objects are the same. Two Methods are the same if
they were declared by the same class and have the same name
and formal parameter types and return type.
if (obj != null && obj instanceof Method) {
Method other = (Method)obj;
if ((getDeclaringClass() == other.getDeclaringClass())
&& (getName() == other.getName())) {
if (!returnType.equals(other.getReturnType()))
return false;
/* Avoid unnecessary cloning */
Class[] params1 = parameterTypes;
Class[] params2 = other.parameterTypes;
if (params1.length == params2.length) {
for (int i = 0; i < params1.length; i++) {
if (params1[i] != params2[i])
return false;
}
return true;
}
}
}
return false;
| public T | getAnnotation(java.lang.Class annotationClass)
if (annotationClass == null)
throw new NullPointerException();
return (T) declaredAnnotations().get(annotationClass);
| public java.lang.annotation.Annotation[] | getDeclaredAnnotations()
return declaredAnnotations().values().toArray(EMPTY_ANNOTATION_ARRAY);
| public java.lang.Class | getDeclaringClass()Returns the Class object representing the class or interface
that declares the method represented by this Method object.
return clazz;
| public java.lang.Object | getDefaultValue()Returns the default value for the annotation member represented by
this Method instance. If the member is of a primitive type,
an instance of the corresponding wrapper type is returned. Returns
null if no default is associated with the member, or if the method
instance does not represent a declared member of an annotation type.
if (annotationDefault == null)
return null;
Class memberType = AnnotationType.invocationHandlerReturnType(
getReturnType());
Object result = AnnotationParser.parseMemberValue(
memberType, ByteBuffer.wrap(annotationDefault),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
getDeclaringClass());
if (result instanceof sun.reflect.annotation.ExceptionProxy)
throw new AnnotationFormatError("Invalid default: " + this);
return result;
| public java.lang.Class[] | getExceptionTypes()Returns an array of Class objects that represent
the types of the exceptions declared to be thrown
by the underlying method
represented by this Method object. Returns an array of length
0 if the method declares no exceptions in its throws clause.
return (Class<?>[]) exceptionTypes.clone();
| private sun.reflect.generics.factory.GenericsFactory | getFactory()
// create scope and factory
return CoreReflectionFactory.make(this, MethodScope.make(this));
| public java.lang.reflect.Type[] | getGenericExceptionTypes()Returns an array of Type objects that represent the
exceptions declared to be thrown by this Method object.
Returns an array of length 0 if the underlying method declares
no exceptions in its throws clause.
If an exception type is a parameterized type, the Type
object returned for it must accurately reflect the actual type
parameters used in the source code.
If an exception type is a type variable or a parameterized
type, it is created. Otherwise, it is resolved.
Type[] result;
if (getGenericSignature() != null &&
((result = getGenericInfo().getExceptionTypes()).length > 0))
return result;
else
return getExceptionTypes();
| private sun.reflect.generics.repository.MethodRepository | getGenericInfo()
// lazily initialize repository if necessary
if (genericInfo == null) {
// create and cache generic info repository
genericInfo = MethodRepository.make(getGenericSignature(),
getFactory());
}
return genericInfo; //return cached repository
| public java.lang.reflect.Type[] | getGenericParameterTypes()Returns an array of Type objects that represent the formal
parameter types, in declaration order, of the method represented by
this Method object. Returns an array of length 0 if the
underlying method takes no parameters.
If a formal parameter type is a parameterized type,
the Type object returned for it must accurately reflect
the actual type parameters used in the source code.
If a formal parameter type is a type variable or a parameterized
type, it is created. Otherwise, it is resolved.
if (getGenericSignature() != null)
return getGenericInfo().getParameterTypes();
else
return getParameterTypes();
| public java.lang.reflect.Type | getGenericReturnType()Returns a Type object that represents the formal return
type of the method represented by this Method object.
If the return type is a parameterized type,
the Type object returned must accurately reflect
the actual type parameters used in the source code.
If the return type is a type variable or a parameterized type, it
is created. Otherwise, it is resolved.
if (getGenericSignature() != null) {
return getGenericInfo().getReturnType();
} else { return getReturnType();}
| private java.lang.String | getGenericSignature()
// Generics infrastructure
return signature;
| sun.reflect.MethodAccessor | getMethodAccessor()
return methodAccessor;
| public int | getModifiers()Returns the Java language modifiers for the method represented
by this Method object, as an integer. The Modifier class should
be used to decode the modifiers.
return modifiers;
| public java.lang.String | getName()Returns the name of the method represented by this Method
object, as a String .
return name;
| public java.lang.annotation.Annotation[][] | getParameterAnnotations()Returns an array of arrays that represent the annotations on the formal
parameters, in declaration order, of the method represented by
this Method object. (Returns an array of length zero if the
underlying method is parameterless. If the method has one or more
parameters, a nested array of length zero is returned for each parameter
with no annotations.) The annotation objects contained in the returned
arrays are serializable. The caller of this method is free to modify
the returned arrays; it will have no effect on the arrays returned to
other callers.
int numParameters = parameterTypes.length;
if (parameterAnnotations == null)
return new Annotation[numParameters][0];
Annotation[][] result = AnnotationParser.parseParameterAnnotations(
parameterAnnotations,
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
getDeclaringClass());
if (result.length != numParameters)
throw new java.lang.annotation.AnnotationFormatError(
"Parameter annotations don't match number of parameters");
return result;
| public java.lang.Class[] | getParameterTypes()Returns an array of Class objects that represent the formal
parameter types, in declaration order, of the method
represented by this Method object. Returns an array of length
0 if the underlying method takes no parameters.
return (Class<?>[]) parameterTypes.clone();
| public java.lang.Class | getReturnType()Returns a Class object that represents the formal return type
of the method represented by this Method object.
return returnType;
| public java.lang.reflect.TypeVariable[] | getTypeParameters()Returns an array of TypeVariable objects that represent the
type variables declared by the generic declaration represented by this
GenericDeclaration object, in declaration order. Returns an
array of length 0 if the underlying generic declaration declares no type
variables.
if (getGenericSignature() != null)
return (TypeVariable<Method>[])getGenericInfo().getTypeParameters();
else
return (TypeVariable<Method>[])new TypeVariable[0];
| public int | hashCode()Returns a hashcode for this Method . The hashcode is computed
as the exclusive-or of the hashcodes for the underlying
method's declaring class name and the method's name.
return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
| public java.lang.Object | invoke(java.lang.Object obj, java.lang.Object args)Invokes the underlying method represented by this Method
object, on the specified object with the specified parameters.
Individual parameters are automatically unwrapped to match
primitive formal parameters, and both primitive and reference
parameters are subject to method invocation conversions as
necessary.
If the underlying method is static, then the specified obj
argument is ignored. It may be null.
If the number of formal parameters required by the underlying method is
0, the supplied args array may be of length 0 or null.
If the underlying method is an instance method, it is invoked
using dynamic method lookup as documented in The Java Language
Specification, Second Edition, section 15.12.4.4; in particular,
overriding based on the runtime type of the target object will occur.
If the underlying method is static, the class that declared
the method is initialized if it has not already been initialized.
If the method completes normally, the value it returns is
returned to the caller of invoke; if the value has a primitive
type, it is first appropriately wrapped in an object. However,
if the value has the type of an array of a primitive type, the
elements of the array are not wrapped in objects; in
other words, an array of primitive type is returned. If the
underlying method return type is void, the invocation returns
null.
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class caller = Reflection.getCallerClass(1);
Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))
? clazz
: obj.getClass());
boolean cached;
synchronized (this) {
cached = (securityCheckCache == caller)
&& (securityCheckTargetClassCache == targetClass);
}
if (!cached) {
Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
synchronized (this) {
securityCheckCache = caller;
securityCheckTargetClassCache = targetClass;
}
}
}
}
if (methodAccessor == null) acquireMethodAccessor();
return methodAccessor.invoke(obj, args);
| public boolean | isBridge()Returns true if this method is a bridge
method; returns false otherwise.
return (getModifiers() & Modifier.BRIDGE) != 0;
| public boolean | isSynthetic()Returns true if this method is a synthetic
method; returns false otherwise.
return Modifier.isSynthetic(getModifiers());
| public boolean | isVarArgs()Returns true if this method was declared to take
a variable number of arguments; returns false
otherwise.
return (getModifiers() & Modifier.VARARGS) != 0;
| void | setMethodAccessor(sun.reflect.MethodAccessor accessor)
methodAccessor = accessor;
// Propagate up
if (root != null) {
root.setMethodAccessor(accessor);
}
| public java.lang.String | toGenericString()Returns a string describing this Method , including
type parameters. The string is formatted as the method access
modifiers, if any, followed by an angle-bracketed
comma-separated list of the method's type parameters, if any,
followed by the method's generic return type, followed by a
space, followed by the class declaring the method, followed by
a period, followed by the method name, followed by a
parenthesized, comma-separated list of the method's generic
formal parameter types. A space is used to separate access
modifiers from one another and from the type parameters or
return type. If there are no type parameters, the type
parameter list is elided; if the type parameter list is
present, a space separates the list from the class name. If
the method is declared to throw exceptions, the parameter list
is followed by a space, followed by the word throws followed by
a comma-separated list of the generic thrown exception types.
If there are no type parameters, the type parameter list is
elided.
The access modifiers are placed in canonical order as
specified by "The Java Language Specification". This is
public, protected or private first,
and then other modifiers in the following order:
abstract, static, final,
synchronized native.
try {
StringBuilder sb = new StringBuilder();
int mod = getModifiers() & LANGUAGE_MODIFIERS;
if (mod != 0) {
sb.append(Modifier.toString(mod) + " ");
}
Type[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append("<");
for(Type typeparm: typeparms) {
if (!first)
sb.append(",");
if (typeparm instanceof Class)
sb.append(((Class)typeparm).getName());
else
sb.append(typeparm.toString());
first = false;
}
sb.append("> ");
}
Type genRetType = getGenericReturnType();
sb.append( ((genRetType instanceof Class)?
Field.getTypeName((Class)genRetType):genRetType.toString()) + " ");
sb.append(Field.getTypeName(getDeclaringClass()) + ".");
sb.append(getName() + "(");
Type[] params = getGenericParameterTypes();
for (int j = 0; j < params.length; j++) {
sb.append((params[j] instanceof Class)?
Field.getTypeName((Class)params[j]):
(params[j].toString()) );
if (j < (params.length - 1))
sb.append(",");
}
sb.append(")");
Type[] exceptions = getGenericExceptionTypes();
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append((exceptions[k] instanceof Class)?
((Class)exceptions[k]).getName():
exceptions[k].toString());
if (k < (exceptions.length - 1))
sb.append(",");
}
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
| public java.lang.String | toString()Returns a string describing this Method . The string is
formatted as the method access modifiers, if any, followed by
the method return type, followed by a space, followed by the
class declaring the method, followed by a period, followed by
the method name, followed by a parenthesized, comma-separated
list of the method's formal parameter types. If the method
throws checked exceptions, the parameter list is followed by a
space, followed by the word throws followed by a
comma-separated list of the thrown exception types.
For example:
public boolean java.lang.Object.equals(java.lang.Object)
The access modifiers are placed in canonical order as
specified by "The Java Language Specification". This is
public, protected or private first,
and then other modifiers in the following order:
abstract, static, final,
synchronized, native.
try {
StringBuffer sb = new StringBuffer();
int mod = getModifiers() & LANGUAGE_MODIFIERS;
if (mod != 0) {
sb.append(Modifier.toString(mod) + " ");
}
sb.append(Field.getTypeName(getReturnType()) + " ");
sb.append(Field.getTypeName(getDeclaringClass()) + ".");
sb.append(getName() + "(");
Class[] params = parameterTypes; // avoid clone
for (int j = 0; j < params.length; j++) {
sb.append(Field.getTypeName(params[j]));
if (j < (params.length - 1))
sb.append(",");
}
sb.append(")");
Class[] exceptions = exceptionTypes; // avoid clone
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append(exceptions[k].getName());
if (k < (exceptions.length - 1))
sb.append(",");
}
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
|
|