Java--反射机制初探

好多天没写博客 项目刚刚上线 来写一写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一下
     */

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章