/* java.lang.reflect.Method - reflection of Java methods
- Copyright (C) 1998, 2001, 2002, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2001, 2002, 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of GNU Classpath.
package java.lang.reflect;
import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
import gnu.java.lang.reflect.MethodSignatureParser;
import java.lang.annotation.Annotation;
-import java.util.Arrays;
/**
* The Method class represents a member method of a class. It also allows
public final class Method
extends AccessibleObject implements Member, GenericDeclaration
{
- Class declaringClass;
- String name;
- int slot;
-
private static final int METHOD_MODIFIERS
= Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
| Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
| Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+ private MethodSignatureParser p;
+
+ VMMethod m;
+
/**
- * This class is uninstantiable.
+ * This class is uninstantiable outside this package.
*/
- private Method(Class declaringClass, String name, int slot)
+ Method(VMMethod m)
{
- this.declaringClass = declaringClass;
- this.name = name;
- this.slot = slot;
+ this.m = m;
+ m.m = this;
}
/**
*/
public Class<?> getDeclaringClass()
{
- return declaringClass;
+ return (Class<?>) m.getDeclaringClass();
}
/**
*/
public String getName()
{
- return name;
+ return m.getName();
}
/**
- * Return the raw modifiers for this method.
- * @return the method's modifiers
- */
- private native int getModifiersInternal();
-
- /**
* Gets the modifiers this method uses. Use the <code>Modifier</code>
* class to interpret the values. A method can only have a subset of the
* following modifiers: public, private, protected, abstract, static,
*/
public int getModifiers()
{
- return getModifiersInternal() & METHOD_MODIFIERS;
+ return m.getModifiersInternal() & METHOD_MODIFIERS;
}
/**
*/
public boolean isBridge()
{
- return (getModifiersInternal() & Modifier.BRIDGE) != 0;
+ return (m.getModifiersInternal() & Modifier.BRIDGE) != 0;
}
/**
*/
public boolean isSynthetic()
{
- return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ return (m.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
}
/**
*/
public boolean isVarArgs()
{
- return (getModifiersInternal() & Modifier.VARARGS) != 0;
+ return (m.getModifiersInternal() & Modifier.VARARGS) != 0;
}
/**
* Gets the return type of this method.
* @return the type of this method
*/
- public native Class<?> getReturnType();
+ public Class<?> getReturnType()
+ {
+ return (Class<?>) m.getReturnType();
+ }
/**
* Get the parameter list for this method, in declaration order. If the
*
* @return a list of the types of the method's parameters
*/
- public native Class<?>[] getParameterTypes();
+ public Class<?>[] getParameterTypes()
+ {
+ return (Class<?>[]) m.getParameterTypes();
+ }
/**
* Get the exception types this method says it throws, in no particular
*
* @return a list of the types in the method's throws clause
*/
- public native Class<?>[] getExceptionTypes();
+ public Class<?>[] getExceptionTypes()
+ {
+ return (Class<?>[]) m.getExceptionTypes();
+ }
/**
* Compare two objects to see if they are semantically equivalent.
*/
public boolean equals(Object o)
{
- // Implementation note:
- // The following is a correct but possibly slow implementation.
- //
- // This class has a private field 'slot' that could be used by
- // the VM implementation to "link" a particular method to a Class.
- // In that case equals could be simply implemented as:
- //
- // if (o instanceof Method)
- // {
- // Method m = (Method)o;
- // return m.declaringClass == this.declaringClass
- // && m.slot == this.slot;
- // }
- // return false;
- //
- // If a VM uses the Method class as their native/internal representation
- // then just using the following would be optimal:
- //
- // return this == o;
- //
- if (!(o instanceof Method))
- return false;
- Method that = (Method)o;
- if (this.getDeclaringClass() != that.getDeclaringClass())
- return false;
- if (!this.getName().equals(that.getName()))
- return false;
- if (this.getReturnType() != that.getReturnType())
- return false;
- if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
- return false;
- return true;
+ return m.equals(o);
}
/**
*/
public int hashCode()
{
- return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+ return m.getDeclaringClass().getName().hashCode() ^ m.getName().hashCode();
}
/**
public String toString()
{
// 128 is a reasonable buffer initial size for constructor
- StringBuilder sb = new StringBuilder(128);
+ CPStringBuilder sb = new CPStringBuilder(128);
Modifier.toString(getModifiers(), sb).append(' ');
sb.append(ClassHelper.getUserName(getReturnType())).append(' ');
sb.append(getDeclaringClass().getName()).append('.');
public String toGenericString()
{
// 128 is a reasonable buffer initial size for constructor
- StringBuilder sb = new StringBuilder(128);
+ CPStringBuilder sb = new CPStringBuilder(128);
Modifier.toString(getModifiers(), sb).append(' ');
Constructor.addTypeParameters(sb, getTypeParameters());
sb.append(getGenericReturnType()).append(' ');
public Object invoke(Object o, Object... args)
throws IllegalAccessException, InvocationTargetException
{
- return invokeNative(o, args, declaringClass, slot);
+ return m.invoke(o, args);
}
- /*
- * NATIVE HELPERS
- */
-
- private native Object invokeNative(Object o, Object[] args,
- Class declaringClass, int slot)
- throws IllegalAccessException, InvocationTargetException;
-
/**
* Returns an array of <code>TypeVariable</code> objects that represents
* the type variables declared by this constructor, in declaration order.
*/
public TypeVariable<Method>[] getTypeParameters()
{
- String sig = getSignature();
- if (sig == null)
- return new TypeVariable[0];
- MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ if (p == null)
+ {
+ String sig = m.getSignature();
+ if (sig == null)
+ return (TypeVariable<Method>[]) new TypeVariable[0];
+ p = new MethodSignatureParser(this, sig);
+ }
return p.getTypeParameters();
}
/**
- * Return the String in the Signature attribute for this method. If there
- * is no Signature attribute, return null.
- */
- private native String getSignature();
-
- /**
* Returns an array of <code>Type</code> objects that represents
* the exception types declared by this method, in declaration order.
* An array of size zero is returned if this method declares no
*/
public Type[] getGenericExceptionTypes()
{
- String sig = getSignature();
- if (sig == null)
- return getExceptionTypes();
- MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ if (p == null)
+ {
+ String sig = m.getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ p = new MethodSignatureParser(this, sig);
+ }
return p.getGenericExceptionTypes();
}
*/
public Type[] getGenericParameterTypes()
{
- String sig = getSignature();
- if (sig == null)
- return getParameterTypes();
- MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ if (p == null)
+ {
+ String sig = m.getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ p = new MethodSignatureParser(this, sig);
+ }
return p.getGenericParameterTypes();
}
*/
public Type getGenericReturnType()
{
- String sig = getSignature();
- if (sig == null)
- return getReturnType();
- MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ if (p == null)
+ {
+ String sig = m.getSignature();
+ if (sig == null)
+ return getReturnType();
+ p = new MethodSignatureParser(this, sig);
+ }
return p.getGenericReturnType();
}
*
* @since 1.5
*/
- public native Object getDefaultValue();
+ public Object getDefaultValue()
+ {
+ return m.getDefaultValue();
+ }
/**
* <p>
* matches the declaration order of the parameters.
* @since 1.5
*/
- public native Annotation[][] getParameterAnnotations();
+ public Annotation[][] getParameterAnnotations()
+ {
+ return m.getParameterAnnotations();
+ }
+
+ /**
+ * Returns the element's annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this element's annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @throws NullPointerException if the annotation class is <code>null</code>.
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+ {
+ // Inescapable as the VM layer is 1.4 based. T will erase to Annotation anyway.
+ @SuppressWarnings("unchecked")
+ T ann = (T) m.getAnnotation(annotationClass);
+ return ann;
+ }
+
+ /**
+ * Returns all annotations directly defined by the element. If there are
+ * no annotations directly associated with the element, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return the annotations directly defined by the element.
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations()
+ {
+ return m.getDeclaredAnnotations();
+ }
}