简单来说,反射就是在运行时可以获取任意 ClassObject 内部所有成员属性,如成员变量、成员方法、构造函数和 Annotation。

首先,我们定义一个注解:

1
2
3
4
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Invoke {
}

对于注解中的参数,有以下解释:

@Target : 注解所修饰的对象范围

@Inherited :表示注解可以被继承

@Documented :表示这个注解应该被JavaDoc工具记录

@Retention :用来声明注解的保留策略

其中@Target和@Retention有以下的一些参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public enum ElementType {

TYPE, 能修饰类,接口和枚举类型

FIELD, 能修饰成员变量

METHOD, 能修饰方法

PARAMETER, 能修饰参数

CONSTRUCTOR, 能修饰构造方法

LOCAL_VARIABLE, 能修饰局部变量

ANNOTATION_TYPE, 能修饰注解

PACKAGE, 能修饰包

TYPE_PARAMETER, 类型参数声明

TYPE_USE 使用类型
}
1
2
3
4
5
6
7
8
public enum RetentionPolicy {

SOURCE, 源码级注解,只会保留在.java源码中,编译后被丢弃,不会保留在.class中

CLASS, 编译时注解。注解信息会保留在.java源码以及.class中。当程序运行时,JVM会丢弃该注解信息

RUNTIME 运行时注解。当运行Java程序时,JVM也会保留该注解信息,可以通过反射获取该注解信息
}

下面,我们来定义一个该注解使用的类:

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
public class UserBean {

private String name;
public int age;

public UserBean(String name, int age) {
this.name = name;
this.age = age;
}

@Invoke
public static void logd() {
Log.e("test", "this is static class");
}

@Invoke
public void publicMethod(String user) {
Log.e("test", "this is public" + user);
}

@Invoke
private void privateMethod() {
Log.e("test", "this is private method");
}
}

上面说过,运行时注解可以通过反射的方式处理:

本文地址: http://www.yppcat.top/2019/03/28/java反射/