java反射

反射机制的作用

通过java语言中的反射机制可以操作字节码文件(可以读和修改字节码文件。)
通过反射机制可以操作代码片段。(class文件。)

获取Class的方式

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
35
36
37
38
39
40
41
42
43
public class TestClass {
public static void main(String[] args) {
//method1
//第一种方式 通过类.class
Class c1 = int.class;
//第二种方式 通过对象.class()
Student s = new Student();
//多态 Student s = new 子类();
Class<? extends Student> c = s.getClass();
Action a = new Action() {
};
Class<? extends Action> c2 = a.getClass();
//第三种方式 Class.forName() 最常用的方式 加载并初始化
try {
Class<?> c3 = Class.forName("com.redbean.reflect.testclass.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}

private static void method1(){
//基本类型
//左边是类的模板加变量 右边是具体的对象
Class c = int.class;
//引用类型
//类类型
Class<Student> c2 = Student.class;
//数组类型
Class<Student[]> c3 = Student[].class;
//接口类型
Class<Action> c4 = Action.class;
}
}

class Student{
private int id;
private String name;
}

interface Action{

}

获取类信息

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public class TestClassSelf {
public static void main(String[] args) {
//类的基本信息
//1.Class对象
Class c = Student.class;
//2.获取运行时字节码的信息
//类的名字
String name = c.getName();
String simpleName = c.getSimpleName();
//name = com.redbean.reflect.find.Student
System.out.println("name = " + name);
//simpleName = Student
System.out.println("simpleName = " + simpleName);
//类所在包
System.out.println("package = " + c.getPackage());
//类的修饰符
System.out.println(Modifier.toString(c.getModifiers())); //没有修饰符
//一个父类 superclass = class java.lang.Object
Class superclass = c.getSuperclass();
System.out.println("superclass = " + superclass);
//接口 interfaces = [interface com.redbean.reflect.find.Action, interface com.redbean.reflect.find.Mark]
Class[] interfaces = c.getInterfaces();
System.out.println("interfaces = " + Arrays.toString(interfaces));

//是否为基本类型
System.out.println(c.isPrimitive());
Class c2 = int.class;
System.out.println(c2.isPrimitive());
Class c3 = Integer.class;
System.out.println(c3.isPrimitive());

//判断某个类是否为某个类的父类
System.out.println(c.isAssignableFrom(Action.class));
System.out.println(Action.class.isAssignableFrom(c));
}
}

class Student implements Action,Mark{
private String name;
int age;
public static int num;

public Student(){}

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

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String sayHello(String name){
return "hello! "+name;
}

@Override
public void run() {

}

@Override
public void star() {

}
}

interface Action{
void run();
}
interface Mark{
void star();
}

类的信息

  • 获取字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Class c = Student.class;
//字段 Field
//获取所有公有字段,包括父类字段的类
//无法获取默认 私有 protected
Field[] fields = c.getFields();
for (Field field : fields) {
System.out.println("变量名:" + field.getName());
System.out.println("参数类型:" + field.getType().getName());
System.out.println("修饰符:" + Modifier.toString(field.getModifiers()));
}

//获取所有声明的字段 包括私有 不能获取父类的字段
Field[] declaredFields = c.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println("变量名:" + declaredField.getName());
System.out.println("参数类型:" + declaredField.getType().getName());
System.out.println("修饰符:" + Modifier.toString(declaredField.getModifiers()));
}
  • 获取方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//方法
//公有方法 可以获取父类
Method[] methods = c.getMethods();
for (Method method : methods) {
System.out.println("方法名称:" + method.getName());
System.out.println("返回类型:" + method.getReturnType().getName());
System.out.println("修饰符:" + Modifier.toString(method.getModifiers()));
System.out.println("参数类型:" + Arrays.toString(method.getParameterTypes()));
System.out.println("参数个数:" + method.getParameterCount());
System.out.println("异常类型:" + method.getExceptionTypes());
}
//所有方法 不可以获取父类
Method[] declaredMethods = c.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("方法名称:" + declaredMethod.getName());
System.out.println("返回类型:" + declaredMethod.getReturnType().getName());
System.out.println("修饰符:" + Modifier.toString(declaredMethod.getModifiers()));
System.out.println("参数类型:" + Arrays.toString(declaredMethod.getParameterTypes()));
System.out.println("参数个数:" + declaredMethod.getParameterCount());
System.out.println("异常类型:" + declaredMethod.getExceptionTypes());
}
  • 获取构造器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//构造器
//共有的 构造器不能继承 只能调用 隐式调用一次
Constructor[] constructors = c.getConstructors();
for (Constructor constructor : constructors) {
System.out.println("名称:" + constructor.getName());
System.out.println("修饰符:" + Modifier.toString(constructor.getModifiers()));
System.out.println("参数类型:" + constructor.getParameterTypes());
System.out.println("参数个数:" + constructor.getParameterCount());
}
//私有的不能拿父类
Constructor[] declaredConstructors = c.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println("名称:" + declaredConstructor.getName());
System.out.println("修饰符:" + Modifier.toString(declaredConstructor.getModifiers()));
System.out.println("参数类型:" + declaredConstructor.getParameterTypes());
System.out.println("参数个数:" + declaredConstructor.getParameterCount());
}
  • 获取注解
1
2
3
4
5
6
7
8
//注解
Annotation[] annotations = c.getAnnotations();
System.out.println(Arrays.toString(annotations));
if (c.isAnnotationPresent(Role.class)){
Role role = (Role) c.getAnnotation(Role.class);
String name = role.name();
System.out.println(name);
}