好多天没写博客 项目刚刚上线 来写一写deom 昨晚复习了一下java的反射机制 写了一个小deom复习下反射机制 代码这东西还是写出来比较爽呀
废话不多说
反射:Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。
也就是说,Java可以加载一个运行时才得知名称的class,获得其完整结构。
这个完整结构是说我们可以通过反射得到里面的任何东西,不管是不是私有的,打破了private,public,protected的各种限制,动态的得到类中的方法
利用反射的步骤以及方法:
第一步:首先得到class文件,可以通过三种方式获得,第一种的Class.forName(“Class”),第二种是通过先new出来一个对象,通过对象去调用自己的class方法,第三种是直接通过类.class方法,都可以得到
第二步:可以通过已经获得的class文件,获得属性,方法,构造函数的方法
第三步:可以选择暴力破解setAccessible(),不然有些private无法得到,然后可以进行逆想做的操作
接下来不说什么,上代码:
首先是测试类Student
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age,String name) {
// TODO Auto-generated constructor stub
this.age=age;
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void testPrint(){
System.out.println("===============通过反射实例化=====================");
}
}
测试Deom
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Reflect {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// 第一步 获得得到反射类的方法 有三种
// 第一种 通过Class.forName(); 第二种 通过getClass 第三种 直接通过类调用.class方法
Class c1 = Class.forName("Student");
Class c2 = Student.class;
Student s1 = new Student();
Class c3 = s1.getClass();
/**
* 当得到class 文件 也就是字节码文件后 便可以得到里面的所有内容,
* 有两个吸引的地方,一个就是动态加载,一个是可以获得里面所有的内容,而不是通过子类或者new出一个对象
* 是直接的得到里面的任何东西,不管是public或者是private或者是hide隐藏的方法
*/
// 第二步 当得到字节码文件之后 可以实例化这个类的对象
Student student = (Student) c1.newInstance();
student.testPrint();
/**
* 此时输出的结果是 ===============通过反射实例化===================== 也就意味着 如果是实例化
* 会直接执行无参构造方法
*/
// 第三步 可以避免构造对象 得到class类中的属性field constructor 构造函数 方法 method
/**
* Field 字段 可以获得所有类中的属性 通过getDeclaredFields或者是getFields的方法
* 前者可以获得的是本类的属性,包含private 后者获得的是本类以及父类的不包含priate属性
*/
Field[] fs = c1.getDeclaredFields();
// 定义可变长的字符串,用来存储属性
StringBuffer sb = new StringBuffer();
// 通过追加的方法,将每个属性拼接到此字符串中
// 最外边的public定义
sb.append(Modifier.toString(c1.getModifiers()) + " class "
+ c1.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);
/**
* 每个field可以拿出来 然后通过setAccessible(true)让private方法进行破解,从而进行设置,绕过对象得到
*/
Field age = c1.getDeclaredField("age");
age.setAccessible(true);// 我可以称之为暴力破解么
age.set(student, 10);
System.out.println(student.getAge());// 此时的输出是10 是不是感觉很神奇 哈哈哈哈
}
/**
* 其他的构造函数 方法等都是类似的步骤 注意: 最好是通过setAccessible()的方法进行暴力破解 不然如果是private的会报异常
* 得到method之后,需要involve一下
*/
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-16 18:12:55