Java-Method類常用方法詳解


一、Method類的定義
Method類位於 java.lang.reflect 包中,主要用於在程序運行狀態中,動態地獲取方法信息
二、Method類的常用方法
  1、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 methodAnnotatedReturnType = method.getAnnotatedReturnType();
// class java.lang.String
System.out.println(methodAnnotatedReturnType.getType());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  2、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());
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  3、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());
}
}
1
2
3
4
5
6
7
8
9
10
11
  4、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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  5、getDeclaredAnnotation(Class<T> annotationClass)

如果該方法對象存在指定類型的注解,則返回該注解,否則返回null
只有類級別的注解會被繼承得到,對於其他對象而言,getAnnotation() 方法與 getDeclaredAnnotation() 方法作用相同
  6、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");
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));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  7、getDeclaredAnnotationsByType(Class<T> annotationClass)

如果該方法對象存在指定類型的注解,則返回該注解數組,否則返回null
只有類級別的注解會被繼承得到,對於其他對象而言,getAnnotationsByType() 方法與 getDeclaredAnnotationsByType() 方法作用相同
  8、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);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  9、getDeclaredAnnotations()

返回該方法對象上的所有注解,如果沒有注解,則返回空數組
只有類級別的注解會被繼承得到,對於其他對象而言,getAnnotations() 方法與 getDeclaredAnnotations() 方法作用相同
  10、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()));
}
}
1
2
3
4
5
6
7
8
9
10
  11、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());
}
}
1
2
3
4
5
6
7
8
9
10
  12、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));
}
}
1
2
3
4
5
6
7
8
9
10
11
  13、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());
}
}
1
2
3
4
5
6
7
8
9
10
  14、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);
}
}
1
2
3
4
5
6
7
8
9
10
11
  15、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());
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  16、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));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
  17、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());
}
}
1
2
3
4
5
6
7
8
9
10
  18、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);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  19、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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  20、getParameterTypes()

返回一個Class對象數組,該數組以聲明順序表示該方法對象的參數對象,會擦除泛型
public class MethodTest<T> {

public void test(T t) {}

public void test(LinkedList<Integer> list) {}

public static void main(String[] args) throws Exception {
Method objectMethod = MethodTest.class.getMethod("test", Object.class);
Method listMethod = MethodTest.class.getMethod("test", LinkedList.class);

Class<?>[] objectParameterTypes = objectMethod.getParameterTypes();
// [class java.lang.Object]
System.out.println(Arrays.toString(objectParameterTypes));
Class<?>[] listParameterTypes = listMethod.getParameterTypes();
// [class java.util.LinkedList]
System.out.println(Arrays.toString(listParameterTypes));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  21、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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  22、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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  23、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));
}
}
1
2
3
4
5
6
7
8
9
10
11
  24、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));
}
}
1
2
3
4
5
6
7
8
9
10
11
  25、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));
}
}
1
2
3
4
5
6
7
8
9
10
11
  26、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());
}
}
1
2
3
4
5
6
7
8
9
10
  27、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());
}
}
1
2
3
4
5
6
7
8
9
10
  28、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());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  29、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());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  30、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());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  31、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();
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());
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
有關synthetic的相關內容,小伙伴可以看下這里
Java 中冷門的 synthetic 關鍵字原理解讀
  32、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());
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM