There a several modifiers that may be part of a method declaration:
- Access modifiers:
public,protected, andprivate- Modifier restricting to one instance:
static- Modifier prohibiting value modification:
final- Modifier requiring override:
abstract- Modifier preventing reentrancy:
synchronized- Modifier indicating implementation in another programming language:
native- Modifier forcing strict floating point behavior:
strictfp- Annotations
The
example lists the modifiers of a method with a given name. It also displays whether the method is synthetic (compiler-generated), of variable arity, or a bridge method (compiler-generated to support generic interfaces).MethodModifierSpyimport 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(" Modifiers: %s%n", Modifier.toString(m.getModifiers())); out.format(" [ synthetic=%-5b var_args=%-5b bridge=%-5b ]%n", m.isSynthetic(), m.isVarArgs(), m.isBridge()); inc(); } out.format("%d matching overload%s found%n", cnt(), (cnt() == 1 ? "" : "s")); // production code should handle this exception more gracefully } catch (ClassNotFoundException x) { x.printStackTrace(); } } }A few examples of the output
produces follow.MethodMdifierSpy$ java MethodModifierSpy java.lang.Object wait public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException Modifiers: public final native [ synthetic=false var_args=false bridge=false ] public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException Modifiers: public final [ synthetic=false var_args=false bridge=false ] public final void java.lang.Object.wait() throws java.lang.InterruptedException Modifiers: public final [ synthetic=false var_args=false bridge=false ] 3 matching overloads found $ java MethodModifierSpy java.lang.StrictMath toRadians public static double java.lang.StrictMath.toRadians(double) Modifiers: public static strictfp [ synthetic=false var_args=false bridge=false ] 1 matching overload found $ java MethodModifierSpy MethodModifierSpy inc private synchronized void MethodModifierSpy.inc() Modifiers: private synchronized [ synthetic=false var_args=false bridge=false ] 1 matching overload found $ 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 Modifiers: public transient [ synthetic=false var_args=true bridge=false ] 1 matching overload found $ java MethodModifierSpy java.lang.String compareTo public int java.lang.String.compareTo(java.lang.String) Modifiers: public [ synthetic=false var_args=false bridge=false ] public int java.lang.String.compareTo(java.lang.Object) Modifiers: public volatile [ synthetic=true var_args=false bridge=true ] 2 matching overloads foundNote that
Method.isVarArgs()returnstrueforClass.getConstructor(). This indicates that the method declaration looks like this:not like this:public Constructor<T> getConstructor(Class<?>... parameterTypes)public Constructor<T> getConstructor(Class<?> [] parameterTypes)Notice that the output for
String.compareTo()contains two methods. The method declared inString.java:and a second synthetic or compiler-generated bridge method. This occurs becausepublic int compareTo(String anotherString);Stringimplements the parameterized interfaceComparable. During type erasure, the argument type of the inherited methodComparable.compareTo()is changed fromjava.lang.Objecttojava.lang.String. Since the parameter types for thecompareTomethods inComparableandStringno longer match after erasure, overriding can not occur. In all other circumstances, this would produce a compile-time error because the interface is not implemented. The addition of the bridge method avoids this problem.
Methodimplementsjava.lang.reflect.AnnotatedElement. Thus any runtime annotations withjava.lang.annotation.RetentionPolicy.RUNTIMEmay be retrieved. For an example of obtaining annotations see the section Examining Class Modifiers and Types.