Java反射的概念
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。有不少Java Web便是利用反射机制实现了强大功能,如Spring。
Java反射机制主要提供下面几种用途:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
- 在运行时修改变量的应用对象
- 实现动态代理
反射涉及的主要的类与作用
Class类与java.lang.reflect类库一起对反射的概念进行了支持,该类库包含了Field,Method以及Constructor类(每个类都实现了Methods)。这些类型的对象是由JVM在运行时创建的,用以表示未知类里面的对应的成员。这样,匿名对象的类信息就能在运行时被完全确定下来,而在编译时不需要知道任何事情。下面主要介绍下涉及到反射的主要的类与接口。
- Class:它表示正在运行的Java应用程序中的类和接口
- Field:提供有关类或接口的属性信息,以及对它的动态访问权限
- Constructor:提供关于类的单个构造方法的信息以及对它的访问权限
- Method:提供关于类或接口中某个方法信息
反射实例
因为可能涉及到一些相关的重复示例代码,这里就先行给出。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
29public class ReflectSample {
private int field1;
private int field2;
private String field3;
public ReflectSample() {
field1 = 1;
field2 = 2;
field3 = "before change";
}
public ReflectSample(int arg1, int arg2) {
this();
}
public void method1() {
}
public void method2(int arg) {
}
public void show(){
System.out.println("Reflect show method...");
}
}
使用java的反射机制,一般需要遵循三步:
1.获得你想操作类的Class对象
2.通过第一步获得的Class对象去取得操作类的方法或是属性名
3.操作第二步取得的方法或是属性
Java运行的时候,某个类无论生成多少个对象,他们都会对应同一个Class对象,它表示正在运行程序中的类和接口。如何取得操作类的Class对象,常用的有三种方式:
1.调用Class的静态方法forName,如上例;
2.使用类的.class语法,如:Class<?> cls = String.class;
3.调用对象的getClass方法,如:String str = “abc”;Class<?> cls = str .getClass();
Constructor类相关实例
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
package com.waterjim.example;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class ConstructorSample {
public static void main(String[] args) {
try {
Class reflectClass = Class.forName("com.waterjim.example.ReflectSample");
Constructor[] constructors = reflectClass.getConstructors();
for (int index = 0; index < constructors.length; index++) {
//构造函数的名字
System.out.println("Constructor " + index + " : " + constructors[index].getName());
//构造函数的访问权限
System.out.println("Constructor Modifier : " + Modifier.toString(constructors[index].getModifiers()));
// 获取构造方法中的参数
Class[] paramTypes = constructors[index].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();
System.out.println("---------------------------------------------------");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}Field类相关实例
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
56package com.waterjim.example;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class FieldSample {
public static void main(String[] args) {
try {
Class reflectClass = Class.forName("com.waterjim.example.ReflectSample");
Field[] fields = reflectClass.getDeclaredFields();
for(Field field : fields){
//变量的名称
System.out.println("Field name : " + field.getName());
//变量的访问权限
System.out.println("Field Modifier : " + Modifier.toString(field.getModifiers())) ;
//变量的类型
System.out.println("Field type : " + field.getType().getName());
System.out.println("---------------------------------------------------------");
System.out.println();
}
System.out.println("Field change------------------------");
//获取私有变量,并改变他的值
//实例化一个对象
ReflectSample reflectSample = (ReflectSample) reflectClass.newInstance();
//获取私有变量对应的Field对象
Field privateField = reflectClass.getDeclaredField("field3");
privateField.setAccessible(true);
System.out.println("Before : " + privateField.get(reflectSample));
//改变其指向的对象引用
privateField.set(reflectSample, new String("after change..."));
System.out.println("Before : " + privateField.get(reflectSample));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}Method类相关实例
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
66package com.waterjim.example;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class MethodSample {
public static void main(String[] args) {
try {
Class reflectClass = Class.forName("com.waterjim.example.ReflectSample");
// 获取指定类的所有方法
// 注意:这里使用的是 getDeclaredMethods(), 还有一个 getMethods(),
// 但是后者不能获取声明为private的方法
Method[] methods = reflectClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println("Method name : " + method.getName());
System.out.println("Method modifier : " + Modifier.toString(method.getModifiers()));
// 获取构造方法中的参数
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();
System.out.println("---------------------------------------------------");
}
System.out.println("Use Method.invoke-----------------------------------");
//实例化一个对象
ReflectSample reflectSample = (ReflectSample) reflectClass.newInstance();
//获取show()对应的Method对象,注意这里使用的是getDeclaredMethod();
Method showMethod = reflectClass.getDeclaredMethod("show");
//如果操作的方法是一个私有方法,需要先设置其为可访问
showMethod.setAccessible(true);
//调用show()方法
showMethod.invoke(reflectSample);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}