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).
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(" 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()
returnstrue
forClass.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);String
implements the parameterized interfaceComparable
. During type erasure, the argument type of the inherited methodComparable.compareTo()
is changed fromjava.lang.Object
tojava.lang.String
. Since the parameter types for thecompareTo
methods inComparable
andString
no 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.
Method
implementsjava.lang.reflect.AnnotatedElement
. Thus any runtime annotations withjava.lang.annotation.RetentionPolicy.RUNTIME
may be retrieved. For an example of obtaining annotations see the section Examining Class Modifiers and Types.