本教程是针对JDK 8编写的。本页面中描述的示例和实践未利用后续版本中引入的改进,并且可能使用不再可用的技术。
请参阅Java语言更改以了解Java SE 9及其后续版本中更新的语言功能的摘要。
请参阅JDK发行说明以获取有关所有JDK版本的新功能、增强功能和已删除或弃用选项的信息。
方法声明中可能包含多个修饰符:
public
、protected
和private
static
final
abstract
synchronized
native
strictfp
示例列出了具有给定名称的方法的修饰符。它还显示方法是否是合成的(由编译器生成)、可变参数的或桥接方法(为了支持泛型接口而由编译器生成)。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
。由于Comparable
和String
中的compareTo
方法的参数类型在擦除后不再匹配,因此无法进行重写。在所有其他情况下,这将产生一个编译时错误,因为接口未被实现。桥接方法的添加避免了这个问题。
Method
实现了java.lang.reflect.AnnotatedElement
。因此,可以获取到任何具有java.lang.annotation.RetentionPolicy.RUNTIME
运行时注解。有关获取注解的示例,请参阅检查类修饰符和类型部分。