请说明一下JAVA中反射的实现过程和作用分别是什么?
Java语言编译后形成.class文件,反射就是通过字节码文件找到一个类,类中的方法及属性等。反射的实现主要通过四个类
Class 类的对象
Constructor 类的构造方法
Field 类的成员函数
Method 类的成员方法
反射机制能够在运行时获取类对类的一些信息进行修改从而使Java拥有了动态特性。
由于反射的特性从而导致了其实private修饰的成员函数并非不可访问。可以通过反射机制获取到并且跳过安全检测并访问
样例代码:
/**
* @author Satsuki
* @time 2019/9/12 15:18
* @description:
*/
public class RUser {
private int id;
private int age;
private String uname;
public RUser() {
}
public RUser(int id, int age, String uname) {
this.id = id;
this.age = age;
this.uname = 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;
}
@Override
public String toString() {
return "RUser{" +
"id=" + id +
", age=" + age +
", uname='" + uname + '\'' +
'}';
}
}
/**
* @author Satsuki
* @time 2019/9/12 15:37
* @description:
* 应用反射API动态的操作
* 类名,属性,方法,构造器等
*/
public class Demo02 {
public static void main(String[] args) {
String path = "priv.wzb.javabase.reflection.RUser";
try {
Class<RUser> clazz = (Class<RUser>) Class.forName(path);
//通过反射API调用构造方法,构造对象
RUser u = clazz.newInstance();//其实是调用了user的无参构造方法
//记得重写类的无参构造器因为反射的应用会调用类的无参构造器生成对象
Constructor<RUser> declaredConstructor = clazz.getDeclaredConstructor(int.class, int.class, String.class);
RUser u2 = declaredConstructor.newInstance(1001, 17, "satsuki");
System.out.println(u2.toString());
//通过反射API调用普通方法
RUser u3 = clazz.newInstance();
System.out.println(u.hashCode()==u3.hashCode());
Method setUname = clazz.getDeclaredMethod("setUname", String.class);
setUname.invoke(u3,"stk3");
System.out.println(u3.getUname());
//通过反射API操作属性
RUser u4 = clazz.newInstance();
Field f = clazz.getDeclaredField("uname");
f.setAccessible(true);//这个属性不用做安全检查直接访问
f.set(u4,"stk4");
System.out.println(u4.getUname());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
可以看到通过调用setAccessible(true)使得可以直接访问设定private成员函数