目录
反射机制的常见操作,实际上就是“Class 对象”的常用方法的使用。一般有如下几种常见操作:
- 动态加载类、动态获取类的信息(属性、方法、构造器)
- 动态构造对象
- 动态调用类和对象的任意方法
- 动态调用和处理属性
- 获取泛型信息
- 处理注解
类名 | 类的作用 |
Class 类 | 代表类的结构信息 |
Method 类 | 代表方法的结构信息 |
Field 类 | 代表属性的结构信息 |
Constructor 类 | 代表构造方法的结构信息 |
Annotation 类 | 代表注解的结构信息 |
为了测试方便,我们先定义一个简单的 User 类
package com.reflex;
public class User {
private int age;
private String uname;
public void printName(){
System.out.println("我的名字是:"+uname);
}
public User(String uname) {
this.uname = uname;
}
public User(int age, String uname) {
super();
this.age = age;
this.uname = uname;
}
public User() {
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
}
操作构造方法(Constructor 类)
Constructor 类的对象代表“构造方法”。我们可以通过 Constructor 对象来操作构造方法, 从而构造对象
反射机制动态调用构造方法
package com.reflex;
import java.lang.reflect.Constructor;
/**
* 测试反射操作构造方法(Constructor类).
*/
public class Test02 {
public static void main(String[ ] args) {
String path = "com.reflex.User";
try {
Class clazz = Class.forName(path);
//获得所有构造方法
Constructor[] cons = clazz.getDeclaredConstructors();
for (Constructor constructor : cons) {
System.out.println(constructor);
}
System.out.println("############");
//获得无参构造方法
Constructor c1 = clazz.getDeclaredConstructor(null);
System.out.println("无参构造方法:"+c1);
//获得带参构造方法
Constructor c2 = clazz.getDeclaredConstructor(int.class,String.class);
System.out.println("带参int、String的构造方法:"+c2);
System.out.println("**********************");
//调用构造方法,构造对象
User user1 = (User) clazz.newInstance(); //调用无参构造方法
User user2 = (User) c1.newInstance(null); //调用无参构造方法
User user3 = (User) c2.newInstance(18,"李斯");//调用带参构造方法传入参数
user1.printName();
user2.printName();
user3.printName();
} catch (Exception e) {
e.printStackTrace();
}
}
}
操作属性(Field 类)
我们可以通过 Field 对象来操作类和对象的属性。这里需要注意一点,通常“属性一般为 private”,因此我们需要“禁用安全检查”,即“setAccessible(true)”。
反射机制操作属性
package com.reflex;
import java.lang.reflect.Field;
/**
* 测试反射操作构造属性(Field类).
*/
public class Test03 {
public static void main(String[ ] args) {
String path = "com.reflex.User";
try {
Class clazz = Class.forName(path);
//获得所有属性
Field[ ] fields = clazz.getDeclaredFields();
for (Field f : fields) {
System.out.println("属性:"+f);
}
System.out.println("############");
//获得指定名字的属性
Field f2 = clazz.getDeclaredField("uname");
System.out.println("通过uname名字获得Field对象:"+f2);
//通过反射给对象的属性赋值
User user = (User) clazz.newInstance();
f2.setAccessible(true); //跳过安全检查,可以直接访问私有属性和方法
f2.set(user, "刘小六");
user.printName();
} catch (Exception e) {
e.printStackTrace();
}
}
}
操作方法(Method 类)
可以通过 Method 对象操作对应的方法,动态的调用方法。
反射机制操作方法
package com.reflex;
import java.lang.reflect.Method;
/**
* 反射操作普通方法(Method类).
*/
public class Test04 {
public static void main(String[ ] args) {
String path = "com.reflex.User";
try {
Class clazz = Class.forName(path);
//获得所有方法
Method[ ] methods = clazz.getDeclaredMethods();
for (Method m : methods) {
System.out.println("方法:"+m);
}
System.out.println("############");
//获得指定名字和参数,获得方法
Method method1 = clazz.getDeclaredMethod("setUname", String.class);
Method method2 = clazz.getDeclaredMethod("printName", null);
//通过反射调用方法
User user = (User) clazz.newInstance();
method1.invoke(user, "老六");
method2.invoke(user, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}