一 测试各种类型的(class,interface, enum, annotation, primitive, type, void)对应的java.lang.Class对象的获取方式
package Reflection;
/**
* 测试各种类型的(class,interface, enum, annotation, primitive, type, void)对应的java.lang.Class对象的获取方式
* @author lenovo
*
*/
public class TestClass {
public static void main(String[] args) {
String path = "Reflection.User"; //要加载类的地址
try {
//对象表示或封装一些数据,一个类被加载后,JVM会创建一个对应该类的Class对象,类的整个结构信息会被放到对应的Class对象中。
//这个Class对象就像一面镜子一样,通过这面镜子我可以看到对应类的全部信息
Class clazz = Class.forName(path); //加载类的内容
System.out.println(clazz);
Class strClazz = String.class;
System.out.println(strClazz);
Class strClazz2 = path.getClass();
//发现String.class和path.getClass()获得的是同一个对象
System.out.println(strClazz == strClazz2);
Class intClazz = int.class;
System.out.println(intClazz);
} catch (Exception e) {
e.printStackTrace();
}
}
}
User:
package Reflection;
public class User {
private int id;
private int age;
private String uname;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
public User(int id, int age, String uname) {
super();
this.id = id;
this.age = age;
this.uname = uname;
}
//javabean必须要有无参构造函数
public User() {
super();
}
public static void main(String[] args) {
}
}
二 利用反射的API,获取类的信息(类的名字、属性、方法、构造器等)
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 利用反射的API,获取类的信息(类的名字、属性、方法、构造器等)
* @author lenovo
*
*/
public class ReflectionAPI {
public static void main(String[] args) {
String path = "Reflection.User"; //要加载类的地址
try {
Class clazz = Class.forName(path); //加载类的内容
//获取类的名字
System.out.println(clazz.getName()); //获得全路径即包名+类名:Reflection.User
System.out.println(clazz.getSimpleName()); //获得类名:User
//获取属性信息
// Field[] fields = clazz.getFields(); //只能获得public的field
Field[] fields = clazz.getDeclaredFields(); //获得全部属性
for(Field temp: fields) {
System.out.println("属性:" + temp);
}
//获得方法信息
Method[] methods = clazz.getDeclaredMethods();
Method m1 = clazz.getDeclaredMethod("getUname", null);
//如果有参数,则必须传递参数类型对应的class对象
Method m2 = clazz.getDeclaredMethod("setUname", String.class);
for(Method temp: methods) {
System.out.println("方法:" + temp);
}
//获得构造器信息
Constructor[] constructors = clazz.getDeclaredConstructors();
for(Constructor temp: constructors) {
System.out.println("构造器:" + temp);
}
//获取制定类型的构造器
Constructor c = clazz.getDeclaredConstructor(int.class, int.class, String.class);
System.out.println("获得本类的构造函数:" + c);
} catch (Exception e) {
e.printStackTrace();
}
}
}
三 通过反射API动态操作:构造器、方法、属性
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 通过反射API动态操作:构造器、方法、属性
* @author lenovo
*
*/
public class ReflectionAPIUse {
public static void main(String[] args) {
String path = "Reflection.User"; //要加载类的地址
try {
Class<User> clazz = (Class<User>) Class.forName(path); //加载类的内容
//通过反射API动态调用构造方法,构造对象
User u = clazz.newInstance(); //实质是调用User的无参构造方法创建对象
System.out.println(u);
//动态调用有参构造函数
Constructor<User> c = clazz.getDeclaredConstructor(int.class, int.class, String.class);
User u2 = c.newInstance(001, 123, "王建");
System.out.println(u2.getUname());
//通过反射API调用普通的方法
User u3 = clazz.newInstance();
Method method = clazz.getDeclaredMethod("setUname", String.class);
method.invoke(u3, "wangjian"); //上面两行等价于u3.setUname("wangjian")
System.out.println(u3.getUname());
//通过反射API操作属性
User u4 = clazz.newInstance();
Field f = clazz.getDeclaredField("uname");
f.setAccessible(true); //这个属性不需要做安全检查了,可以直接访问
f.set(u4, "计算机小白"); //通过反射写属性的值
System.out.println(u4.getUname()); //通过反射直接读属性的值
} catch (Exception e) {
e.printStackTrace();
}
}
}