Java反射实践

实践是最好的学习方法,光看理论的话,很容易忘,实践一下比较好理解,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解。

一、了解一些概念:

1)java反射功能包含:

  1. 可以判断运行时对象所属的类
  2. 可以判断运行时对象所具有的成员变量和方法
  3. 通过反射甚至可以调用到private的方法
  4. 生成动态代理

2) 实现Java反射的类:

  1. Class:它表示正在运行的Java应用程序中的类和接口
  2. Field:提供有关类或接口的属性信息,以及对它的动态访问权限
  3. Constructor:提供关于类的单个构造方法的信息以及对它的访问权限
  4. Method:提供关于类或接口中某个方法信息

注意:Class类是Java反射中最重要的一个功能类,所有获取对象的信息(包括:方法/属性/构造方法/访问权限)都需要它来实现

3)编写Java反射程序的步骤:

  1. 必须首先获取一个类的Class对象
    例如:
      Class c1 = Test.class;
      Class c2 = Class.forName(“com.reflection.Test”);
      Class c3 = new Test().getClass();
  2. 然后分别调用Class对象中的方法来获取一个类的属性/方法/构造方法的结构

二、实例

1.调用Class对象中的方法来获取一个类的属性/方法/构造方法

定义一个User类

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
package com.reflection;
public class User {
public User() {
super();
}
public User(String name) {
super();
this.name = name;
}
public User(int age) {
super();
this.age = age;
}
public User(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
public void print(){
System.out.println("jerry");
System.out.println(21);
}
public void printLn(String name,int age){
System.out.println(name);
System.out.println(age);
}
private String name;
private int age;
}

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package com.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class TestReflection {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException {
// 获取一个类的Class对象
Class c1 = User.class;
Class c2 = Class.forName("com.reflection.User");
Class c3 = new User().getClass();
// 获取指定类的名
System.out.println(c1.getName());
System.out.println(c2.getName());
System.out.println(c3.getName());
// 获取指定的包名
String packageName = c2.getPackage().getName();
System.out.println(packageName);
// 获取类的修饰符
int mod = c2.getModifiers();
String modifier = Modifier.toString(mod);
System.out.println("modifier = " + modifier);
// 获取指定类的父类
Class superClazz = c2.getSuperclass();
String superClazzName = superClazz.getName();
System.out.println("superClazzName = " + superClazzName);
// 获取指定类的成员变量
Field[] fields = c2.getDeclaredFields();
for (Field field : fields) {
// 获取每个字段的访问修饰符
modifier = Modifier.toString(field.getModifiers());
Class type = field.getType(); // 获取字段的数据类型所对应的Class对象
String name = field.getName(); // 获取字段名
if (type.isArray()) { // 如果是数组类型则需要特别处理
String arrType = type.getComponentType().getName() + "[]";
System.out.println("" + modifier + " " + arrType + " " + name
+ ";");
} else {
System.out.println("" + modifier + " " + type + " " + name
+ ";");
}
}
// 获取类的构造方法
Constructor[] constructors = c2.getDeclaredConstructors();
for (Constructor constructor : constructors) {
String name = constructor.getName(); // 构造方法名
modifier = Modifier.toString(constructor.getModifiers()); // 获取访问修饰符
System.out.println("" + modifier + " " + name + "(");
Class[] paramTypes = constructor.getParameterTypes(); // 获取构造方法中的参数
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) {
System.out.print(",");
}
if (paramTypes[i].isArray()) {
System.out.println(paramTypes[i].getComponentType()
.getName() + "[]");
} else {
System.out.print(paramTypes[i].getName());
}
}
System.out.println(");");
}
//获取成员方法
Method[] methods = c1.getDeclaredMethods();
for (Method method: methods) {
modifier = Modifier.toString(method.getModifiers());
Class returnType = method.getReturnType(); //获取方法的返回类型
if (returnType.isArray()) {
String arrType = returnType.getComponentType
().getName()+"[]";
System.out.print(""+modifier+" " + arrType + " " +
method.getName() + "(");
} else {
System.out.print("" + modifier + " " +
returnType.getName() + " " + method.getName() + "(");
}
Class[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) {
System.out.print(",");
}
if (paramTypes[i].isArray()) {
System.out.println(paramTypes
[i].getComponentType().getName()+"[]");
} else {
System.out.print(paramTypes[i].getName());
}
}
System.out.println(");");
}
}
}

输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
com.reflection.User
com.reflection.User
com.reflection.User
com.reflection
modifier = public
superClazzName = java.lang.Object
private class java.lang.String name;
private int age;
public com.reflection.User(
);
public java.lang.String getName();
public void setName(java.lang.String);
public void setAge(int);
public int getAge();

2.通过Class实例化其他类的对象

1)通过无参构造实例化对象

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
package com.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class TestReflection {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args){
// 获取一个类的Class对象
Class c2=null;
try {
c2 = Class.forName("com.reflection.User");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
User user=null;
try {
user=(User) c2.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
user.setAge(21);
user.setName("jerry");
System.out.println(user.toString());
}
}

输出结果如下:

1
User [name=jerry, age=21]

但是注意一下,当我们把User中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误:

1
2
3
4
5
6
7
8
java.lang.InstantiationException: com.reflection.User
at java.lang.Class.newInstance(Unknown Source)
at com.reflection.TestReflection.main(TestReflection.java:26)
Caused by: java.lang.NoSuchMethodException: com.reflection.User.<init>()
at java.lang.Class.getConstructor0(Unknown Source)
... 2 more
Exception in thread "main" java.lang.NullPointerException
at com.reflection.TestReflection.main(TestReflection.java:35)

所以大家以后再编写使用Class实例化其他类的对象的时候,一定要自己定义无参的构造函数

2)通过有参构造实例化对象

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
package com.reflection;
import java.lang.reflect.Constructor;
public class TestReflection {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args){
// 获取一个类的Class对象
Class<?> c2=null;
try {
c2 = Class.forName("com.reflection.User");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
User user1=null;
User user2=null;
User user3=null;
User user4=null;
//取得全部的构造函数
Constructor<?> cons[]=c2.getConstructors();
try {
user1=(User) cons[0].newInstance();
user2=(User) cons[1].newInstance("jerry");
user3=(User) cons[2].newInstance(21);
user4=(User) cons[3].newInstance("jerry",21);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(user1);
System.out.println(user2);
System.out.println(user3);
System.out.println(user4);
}
}

输出入下:

1
2
3
4
[null 0]
[jerry 0]
[null 21]
[jerry 21]

3)通过反射调用方法

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
79
80
81
82
83
package com.reflection;
import java.lang.reflect.Method;
public class TestReflection {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) {
// 获取一个类的Class对象
Class<?> c2 = null;
Object obj = null;
try {
c2 = Class.forName("com.reflection.User");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
obj = c2.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// 调用User类中的print方法
Method method = c2.getMethod("print");
method.invoke(c2.newInstance());
// 调用User类中的printLn方法
method = c2.getMethod("printLn", String.class, int.class);
method.invoke(obj, "jerry", 21);
// 调用get/set方法
setter(obj, "Name", "tom", String.class);
getter(obj, "Name");
setter(obj, "Age", 22, int.class);
getter(obj, "Age");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param obj
* 操作的对象
* @param att
* 操作的属性
* */
public static void getter(Object obj, String att) {
try {
Method method = obj.getClass().getMethod("get" + att);
System.out.println(method.invoke(obj));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param obj
* 操作的对象
* @param att
* 操作的属性
* @param value
* 设置的值
* @param type
* 参数的属性
* */
public static void setter(Object obj, String att, Object value,
Class<?> type) {
try {
Method method = obj.getClass().getMethod("set" + att, type);
method.invoke(obj, value);
} catch (Exception e) {
e.printStackTrace();
}
}
}

输出结果如下:

1
2
3
4
5
6
jerry
21
jerry
21
tom
22

4)通过反射操作属性

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
package com.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestReflection {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) {
// 获取一个类的Class对象
Class<?> c2 = null;
Object obj = null;
try {
c2 = Class.forName("com.reflection.User");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
obj = c2.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Field field;
try {
field = c2.getDeclaredField("name");
field.setAccessible(true);
field.set(obj, "jack");
System.out.println(field.get(obj));
} catch (Exception e) {
e.printStackTrace();
}
}
}

输出结果如下:

1
jack

热评文章