文档

Java™教程
隐藏目录
检索和解析方法修饰符
路径: 反射API
课程: 成员
章节: 方法

检索和解析方法修饰符

方法声明中可能包含多个修饰符:

MethodModifierSpy示例列出了具有给定名称的方法的修饰符。它还显示方法是否是合成的(由编译器生成)、可变参数的或桥接方法(为了支持泛型接口而由编译器生成)。

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import static java.lang.System.out;

public class MethodModifierSpy {

    private static int count;
    private static synchronized void inc() { count++; }
    private static synchronized int cnt() { return count; }

    public static void main(String... args) {
	try {
	    Class<?> c = Class.forName(args[0]);
	    Method[] allMethods = c.getDeclaredMethods();
	    for (Method m : allMethods) {
		if (!m.getName().equals(args[1])) {
		    continue;
		}
		out.format("%s%n", m.toGenericString());
		out.format("  修饰符:  %s%n",
			   Modifier.toString(m.getModifiers()));
		out.format("  [ 合成=%-5b 可变参数=%-5b 桥接=%-5b ]%n",
			   m.isSynthetic(), m.isVarArgs(), m.isBridge());
		inc();
	    }
	    out.format("找到%d个匹配的重载%n", cnt(),
		       (cnt() == 1 ? "" : "s"));

        // 生产代码应更优雅地处理此异常
	} catch (ClassNotFoundException x) {
	    x.printStackTrace();
	}
    }
}

MethodModifierSpy产生的输出的几个示例如下。

$ java MethodModifierSpy java.lang.Object wait
public final void java.lang.Object.wait() throws java.lang.InterruptedException
  修饰符:  public final
  [ 合成=false 可变参数=false 桥接=false ]
public final void java.lang.Object.wait(long,int)
  throws java.lang.InterruptedException
  修饰符:  public final
  [ 合成=false 可变参数=false 桥接=false ]
public final native void java.lang.Object.wait(long)
  throws java.lang.InterruptedException
  修饰符:  public final native
  [ 合成=false 可变参数=false 桥接=false ]
找到3个匹配的重载
$ java MethodModifierSpy java.lang.StrictMath toRadians
public static double java.lang.StrictMath.toRadians(double)
  修饰符:  public static strictfp
  [ synthetic=false var_args=false bridge=false ]
找到1个匹配的重载
$ java MethodModifierSpy MethodModifierSpy inc
private synchronized void MethodModifierSpy.inc()
  修饰符: private synchronized
  [ synthetic=false var_args=false bridge=false ]
找到1个匹配的重载
$ java MethodModifierSpy java.lang.Class getConstructor
public java.lang.reflect.Constructor<T> java.lang.Class.getConstructor
  (java.lang.Class<T>[]) throws java.lang.NoSuchMethodException,
  java.lang.SecurityException
  修饰符: public transient
  [ synthetic=false var_args=true bridge=false ]
找到1个匹配的重载
$ java MethodModifierSpy java.lang.String compareTo
public int java.lang.String.compareTo(java.lang.String)
  修饰符: public
  [ synthetic=false var_args=false bridge=false ]
public int java.lang.String.compareTo(java.lang.Object)
  修饰符: public volatile
  [ synthetic=true  var_args=false bridge=true  ]
找到2个匹配的重载

请注意,Method.isVarArgs()对于Class.getConstructor()返回true。这表示方法声明如下:

public Constructor<T> getConstructor(Class<?>... parameterTypes)

而不是:

public Constructor<T> getConstructor(Class<?> [] parameterTypes)

注意,String.compareTo()的输出包含两个方法。在String.java中声明的方法为:

public int compareTo(String anotherString);

还有一个第二个合成的或编译器生成的桥接方法。这是因为String实现了参数化接口Comparable。在类型擦除期间,从继承的方法Comparable.compareTo()的参数类型由java.lang.Object更改为java.lang.String。由于ComparableString中的compareTo方法的参数类型在擦除后不再匹配,因此无法进行重写。在所有其他情况下,这将产生一个编译时错误,因为接口未被实现。桥接方法的添加避免了这个问题。

Method实现了java.lang.reflect.AnnotatedElement。因此,可以获取到任何具有java.lang.annotation.RetentionPolicy.RUNTIME运行时注解。有关获取注解的示例,请参阅检查类修饰符和类型部分。


上一页: 获取方法参数的名称
下一页: 调用方法