1 反射原理(来源于网络):
1.1主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
1.2反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。 (来自Sun)
2 具体实现:
2.1反射机制获取类有三种方法,以获取Employee类型为例子:
// 第一种方式: test.User必须是全类名
Class u1 = Class.forName("test.User");
// 第二种方式:
Class u2 = User.class;
// 第三种方式:
// java语言中任何一个java对象都有getClass 方法
User u = new User();
Class u3 = u.getClass(); //u3是运行时类 (u的运行时类是User)
System.out.println(u1); // class test.User
System.out.println(u2); // class test.User
System.out.println(u3); // class test.User
User.java
package test;
public class User {
private String name;
private protected age;
public String sex;
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;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
2.2 获取类以后就可以利用newInstance创建它的对象:
// 创建此Class 对象所表示的类的一个新实例
Class u1 = Class.forName("test.User");
Object o = u1.newInstance(); //调用了Employee的无参数构造方法.
System.out.println(o); // test.User@3853cb28
2.3其他操作方法
2.3.1 获取所有的属性的写法:
//获取所有的属性?
Class u1 = Class.forName("test.User");
Field[] fs = u1.getDeclaredFields();
// 定义可变长的字符串,用来存储属性
StringBuffer sb = new StringBuffer();
// 通过追加的方法,将每个属性拼接到此字符串中
// 最外边的public定义
sb.append(Modifier.toString(u1.getModifiers()) + " class " + u1.getSimpleName() +"{\n");
// 里边的每一个属性
for(Field field:fs){
sb.append("\t");// 空格
sb.append(Modifier.toString(field.getModifiers())+" ");// 获得属性的修饰符,例如public,static等等
sb.append(field.getType().getSimpleName() + " ");// 属性的类型的名字
sb.append(field.getName()+";\n");// 属性的名字+回车
}
sb.append("}");
System.out.println(sb);
/*sb结果
public class User{
private String name;
protected int age;
public String sex;
}*/
2.3.2操作特定的属性:
Class u1 = Class.forName("test.User");
// 获取name属性
Field idF = u1.getDeclaredField("name"); // name属性不存在时候报错java.lang.NoSuchFieldException: name
// 实例化这个类
Object o1 = u1.newInstance();
// 把私有Field变成可访问的 ,公有和保护字段原本就是可访问的
// 缺少报错java.lang.IllegalAccessException: Class test.ReflectedTest can not access a member of class test.User with modifiers "private"
idF.setAccessible(true);
// 给o对象的id属性赋值"110"
idF.set(o1, "110");
System.out.println(idF.get(o1)); // 110
Field sexF = u1.getDeclaredField("sex");
sexF.set(o1, "女");
System.out.println(sexF.get(o1)); // 女
Field ageF = u1.getDeclaredField("age");
ageF.set(o1, 18);
System.out.println(ageF.get(o1)); // 18
3 应用:
3.1把未知属性pojo对象转化为
Class u1 = Class.forName("test.User");
// 获取name属性
Field idF = u1.getDeclaredField("name"); // name属性不存在时候报错java.lang.NoSuchFieldException: name
// 实例化这个类
Object o1 = u1.newInstance();
// 把私有Field变成可访问的 ,公有和保护字段原本就是可访问的
// 缺少报错java.lang.IllegalAccessException: Class test.ReflectedTest can not access a member of class test.User with modifiers "private"
idF.setAccessible(true);
// 给o对象的id属性赋值"110"
idF.set(o1, "110");
System.out.println(idF.get(o1)); // 110
Field sexF = u1.getDeclaredField("sex");
sexF.set(o1, "女");
System.out.println(sexF.get(o1)); // 女
Field ageF = u1.getDeclaredField("age");
ageF.set(o1, 18);
System.out.println(ageF.get(o1)); // 18
Map<String, Object> mapValue = new HashMap<>();
for (Field field : fs) {
field.setAccessible( true );
mapValue.put(field.getName(), field.get(o1));
}
System.out.println(mapValue); // {sex=女, age=18, name=110}