相关文章:
这次主要整理下 Java 中 Method 类的常用方法
一、Method 类的定义
- Method 类位于 java.lang.reflect 包中,主要用于在程序运行状态中,动态地获取方法信息
二、Method 类常用方法
-
getAnnotatedReturnType()
-
返回一个 AnnotatedType 对象,该对象表示使用类型来指定由该可执行文件表示的方法或构造函数的返回类型
public class MethodTest { public String test() { return null; } public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); AnnotatedType annotatedReturnType = method.getAnnotatedReturnType(); // class java.lang.String System.out.println(annotatedReturnType.getType()); } }
-
-
getAnnotatedExceptionTypes()
-
返回一个 AnnotatedType 对象数组,这些对象表示使用类型来指定由该可执行文件表示的方法或构造函数声明的异常
public class MethodTest { public void test() throws NullPointerException, ClassNotFoundException {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); AnnotatedType[] annotatedExceptionTypes = method.getAnnotatedExceptionTypes(); for (AnnotatedType annotatedExceptionType : annotatedExceptionTypes) { // class java.lang.NullPointerException // class java.lang.ClassNotFoundException System.out.println(annotatedExceptionType.getType()); } } }
-
-
getAnnotatedReceiverType()
-
返回一个 AnnotatedType 对象,该对象表示使用类型来指定该可执行对象表示的方法或构造函数的接收者类型
public class MethodTest { public void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); AnnotatedType annotatedReceiverType = method.getAnnotatedReceiverType(); // class lang.reflect.MethodTest System.out.println(annotatedReceiverType.getType()); } }
-
-
getAnnotation(Class<T> annotationClass)
-
如果该方法对象存在指定类型的注解,则返回该注解,否则返回 null
-
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotation() 方法与 getDeclaredAnnotation() 方法作用相同
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MethodAnnotation { String key(); String value(); } public class MethodTest { @MethodAnnotation(key = "key", value = "value") public void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); MethodAnnotation annotation = method.getAnnotation(MethodAnnotation.class); // @lang.reflect.MethodAnnotation(value=value, key=key) System.out.println(annotation); } }
-
-
getDeclaredAnnotation(Class<T> annotationClass)
-
如果该方法对象存在指定类型的注解,则返回该注解,否则返回 null
-
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotation() 方法与 getDeclaredAnnotation() 方法作用相同
-
-
getAnnotationsByType(Class<T> annotationClass)
-
如果该方法对象存在指定类型的注解,则返回该注解数组,否则返回 null
-
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotationsByType() 方法与 getDeclaredAnnotationsByType() 方法作用相同
-
getAnnotationsByType() 方法与 getAnnotation() 方法的区别在于:getAnnotationsByType() 方法会检查修饰该方法对象的注解是否为可重复类型注解,如果是则会返回修饰该方法对象的一个或多个注解
-
@Repeatable 用于声明注解为可重复类型注解
-
当声明为可重复类型注解后,如果方法注解仍为一个,则 getAnnotation() 方法会正常返回,如果方法注解为多个,则 getAnnotation() 方法会返回 null
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Repeatable(RepeatableAnnotation.class) public @interface MethodAnnotation { String key(); String value(); } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface RepeatableAnnotation { MethodAnnotation[] value(); } public class MethodTest { @MethodAnnotation(key = "key1", value = "value1") @MethodAnnotation(key = "key2", value = "value2") public void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); // null System.out.println(method.getAnnotation(MethodAnnotation.class)); MethodAnnotation[] annotationsByType = method.getAnnotationsByType(MethodAnnotation.class); // [@lang.reflect.MethodAnnotation(value=value1, key=key1), @lang.reflect.MethodAnnotation(value=value2, key=key2)] System.out.println(Arrays.toString(annotationsByType)); } }
-
-
getDeclaredAnnotationsByType(Class<T> annotationClass)
-
如果该方法对象存在指定类型的注解,则返回该注解数组,否则返回 null
-
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotationsByType() 方法与 getDeclaredAnnotationsByType() 方法作用相同
-
-
getAnnotations()
-
返回该方法对象上的所有注解,如果没有注解,则返回空数组
-
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotations() 方法与 getDeclaredAnnotations() 方法作用相同
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MethodAnnotation { String key(); String value(); } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation { String key(); String value(); } public class MethodTest { @MethodAnnotation(key = "key1", value = "value1") @TestAnnotation(key = "key2", value = "value2") public void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { // @lang.reflect.MethodAnnotation(value=value1, key=key1) // @lang.reflect.Parameter.TestAnnotation(key=key2, value=value2) System.out.println(annotation); } } }
-
-
getDeclaredAnnotations()
-
返回该方法对象上的所有注解,如果没有注解,则返回空数组
-
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotations() 方法与 getDeclaredAnnotations() 方法作用相同
-
-
getModifiers()
-
返回修饰该方法对象修饰符的整数形式,使用 Modifier 类对其进行解码
public class MethodTest { public void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); // public System.out.println(Modifier.toString(method.getModifiers())); } }
-
-
getName()
-
返回方法对象名称
public class MethodTest { public void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); // test System.out.println(method.getName()); } }
-
-
isAnnotationPresent(Class<? extends Annotation> annotationClass)
-
如果该方法对象上有指定类型的注解,则返回 true,否则为 false
public class MethodTest { @MethodAnnotation(key = "key", value = "value") public void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); // true System.out.println(method.isAnnotationPresent(MethodAnnotation.class)); } }
-
-
isVarArgs()
-
如果该方法对象的参数中存在 可变参,则返回 true,否则为 false
public class MethodTest { public void test(String ... args) {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test", String[].class); // true System.out.println(method.isVarArgs()); } }
-
-
getDeclaringClass()
-
返回该方法对象表示的方法所在类的 Class 对象
public class MethodTest { public void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); Class<?> declaringClass = method.getDeclaringClass(); // class lang.reflect.MethodTest System.out.println(declaringClass); } }
-
-
getAnnotatedParameterTypes()
-
返回一个 AnnotatedType 对象数组,这些对象表示使用类型来指定由该可执行文件表示的方法或构造函数的形式参数类型
public class MethodTest { public void test(String name, Integer age) {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test", String.class, Integer.class); AnnotatedType[] annotatedParameterTypes = method.getAnnotatedParameterTypes(); for (AnnotatedType annotatedParameterType : annotatedParameterTypes) { // class java.lang.String // class java.lang.Integer System.out.println(annotatedParameterType.getType()); } } }
-
-
getParameterAnnotations()
-
返回一组注解数组,这些注解以声明顺序修饰该方法对象的参数
public class MethodTest { public void test(@ParameterAnnotation(key = "key1", value = "value1") String name, @ParameterAnnotation(key = "key2", value = "value2") Integer age) {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test", String.class, Integer.class); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); // [[@lang.reflect.ParameterAnnotation(key=key1, value=value1)], [@lang.reflect.ParameterAnnotation(key=key2, value=value2)]] System.out.println(Arrays.deepToString(parameterAnnotations)); } }
-
-
getParameterCount()
-
返回该方法对象的参数个数 (无论是显式声明的还是隐式声明的或不声明的)
public class MethodTest { public void test(String name, Integer age) {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test", String.class, Integer.class); // 2 System.out.println(method.getParameterCount()); } }
-
-
getParameters()
-
返回一个参数对象数组,该数组表示该方法对象的所有参数
public class MethodTest { public void test(String name, Integer age) {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test", String.class, Integer.class); Parameter[] parameters = method.getParameters(); for (Parameter parameter : parameters) { // java.lang.String name // java.lang.Integer age System.out.println(parameter); } } }
-
-
getDefaultValue()
-
返会该注解方法对象表示的成员默认值
-
如果成员属于基本数据类型,则返回对应的包装类实例
-
如果没有默认值或者该方法实例不表示注解方法,则返回 null
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MethodAnnotation { String key() default "default key"; String value() default "default value"; } public class MethodTest { public static void main(String[] args) throws Exception { Method key = MethodAnnotation.class.getMethod("key"); Method value = MethodAnnotation.class.getMethod("value"); Object defaultValue1 = key.getDefaultValue(); Object defaultValue2 = value.getDefaultValue(); // default key System.out.println(defaultValue1); // default value System.out.println(defaultValue2); } }
-
-
getParameterTypes()
-
返回一个 Class 对象数组,该数组以声明顺序表示该方法对象的参数对象 (擦除泛型)
public class MethodTest<T> { public void test(T t, LinkedList<Integer> list) {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getMethod("test", Object.class, LinkedList.class); Class<?>[] parameterTypes = method.getParameterTypes(); // [class java.lang.Object, class java.util.LinkedList] System.out.println(Arrays.toString(parameterTypes)); } }
-
-
getReturnType()
-
返回一个 Class 对象,该 Class 对象表示该方法对象的返回对象 (擦除泛型)
public class MethodTest<T> { public T test(T t) { return t; } public static void main(String[] args) throws Exception { Method method = MethodTest.class.getMethod("test", Object.class); Class<?> returnType = method.getReturnType(); // class java.lang.Object System.out.println(returnType); } }
-
-
getGenericReturnType()
-
返回一个 Type 对象,该 Type 对象表示该方法对象的返回类型 (保留泛型)
public class MethodTest<T> { public T test(T t) { return t; } public static void main(String[] args) throws Exception { Method method = MethodTest.class.getMethod("test", Object.class); Type genericReturnType = method.getGenericReturnType(); // T System.out.println(genericReturnType); } }
-
-
getExceptionTypes()
-
返回一个 Class 对象数组,该数组表示由该方法对象抛出的异常对象 (擦除泛型)
public class MethodTest<T> { public <T extends Exception> void test() throws T, NullPointerException {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getMethod("test"); Class<?>[] exceptionTypes = method.getExceptionTypes(); // [class java.lang.Exception, class java.lang.NullPointerException] System.out.println(Arrays.toString(exceptionTypes)); } }
-
-
getGenericExceptionTypes()
-
返回一个 Type 对象数组,该数组表示由该方法对象抛出的异常类型 (保留泛型)
public class MethodTest<T> { public <T extends Exception> void test() throws T, NullPointerException {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getMethod("test"); Type[] genericExceptionTypes = method.getGenericExceptionTypes(); // [T, class java.lang.NullPointerException] System.out.println(Arrays.toString(genericExceptionTypes)); } }
-
-
getTypeParameters()
-
返回一个 TypeVariable 对象数组,该数组表示该方法对象声明列表上的类型变量数组
public class MethodTest<T, V> { public <T, V> void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getMethod("test"); TypeVariable<Method>[] typeParameters = method.getTypeParameters(); // [T, V] System.out.println(Arrays.toString(typeParameters)); } }
-
-
toString()
-
返回该方法对象的字符串表示形式 (擦除泛型)
public class MethodTest<T, V> { public <T, V> void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getMethod("test"); // public void lang.reflect.MethodTest.test() System.out.println(method.toString()); } }
-
-
toGenericString()
-
返回该方法对象的字符串表示形式 (保留泛型)
public class MethodTest<T, V> { public <T, V> void test() {} public static void main(String[] args) throws Exception { Method method = MethodTest.class.getMethod("test"); // public <T,V> void lang.reflect.MethodTest.test() System.out.println(method.toGenericString()); } }
-
-
isAccessible()
-
获取该方法对象的可访问标志
public class MethodTest { private void test() {} } public class Test { public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); // false System.out.println(method.isAccessible()); } }
-
-
setAccessible(boolean flag)
-
设置该方法对象的可访问标志
-
在其他类里调用该方法对象时,如果该方法为私有方法,需要设置访问标志为 true,否则会报异常
public class MethodTest { private void test() {} } public class Test { public static void main(String[] args) throws Exception { Method method = MethodTest.class.getDeclaredMethod("test"); method.setAccessible(true); // test System.out.println(method.getName()); } }
-
-
isDefault()
-
判断该方法对象是否为默认方法,如果是则返回 true,否则为 false
public interface Interface { default void test() { System.out.println("这是一个默认方法"); } } public class MethodTest implements Interface { public static void main(String[] args) throws Exception { Method method = MethodTest.class.getMethod("test"); // true System.out.println(method.isDefault()); } }
-
-
isSynthetic()
-
判断该方法对象是否为合成方法,如果是则返回 true,否则为 false
-
在内部类 InnerClass 中,name 是一个私有属性,而我们在外部类 MethodTest 中,直接引用了这个属性,因此编译器会生成一个合成方法,用于绕开 private 私有属性的限制
public class MethodTest { private class InnerClass { private String name = "小明"; } public static void main(final String[] arguments) { InnerClass innerClass = new MethodTest().new InnerClass(); // name: 小明 System.out.println("name: " + innerClass.name); Method[] declaredMethods = innerClass.getClass().getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { // 【static java.lang.String lang.reflect.MethodTest$InnerClass.access$100(lang.reflect.MethodTest$InnerClass)】 isSynthetic(): true System.out.println("【" + declaredMethod + "】" + " isSynthetic(): " + declaredMethod.isSynthetic()); } } }
-
有关 synthetic 的相关内容,小伙伴可以看下这里
-
-
isBridge()
-
判断该方法对象是否桥接方法,如果是则返回 true,否则为 false
-
桥接方法: 是 JDK1.5 引入泛型后,为了使 Java 的泛型方法生成的字节码和 1.5 版本前的字节码相兼容,由编译器自动生成的方法
public interface Interface<T> { T test(T t); } public class MethodTest implements Interface<String> { @Override public String test(String str) { return str; } public static void main(final String[] arguments) { Method[] declaredMethods = MethodTest.class.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { //【public static void lang.reflect.MethodTest.main(java.lang.String[])】 isBridge(): false //【public java.lang.String lang.reflect.MethodTest.test(java.lang.String)】 isBridge(): false //【public java.lang.Object lang.reflect.MethodTest.test(java.lang.Object)】 isBridge(): true System.out.println("【" + declaredMethod + "】" + " isBridge(): " + declaredMethod.isBridge()); } } }
-
有关 bridge 的相关内容,小伙伴可以看下这里
-