关于反射的简单理解与运用

反射机制:对于一个类在运行状态中能够知道这个类所有的属性与方法,对于一个对象能够调用它任意的方法与属性,也就是动态操纵java程序的能力。反射机制可以跳过权限去调用对象甚至改造对象(比如获取private成员),功能是比较强大的。

1.获取class类型对象实例

class类型对象保存了类属性的描述信息。

package test;

import java.lang.reflect.*;
import java.util.Arrays;

public class Test06 {
    private int a=0;

    public Test06(int a) {
        this.a = a;
    }

    public Test06() {
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Test06 test06=new Test06();

        //方法一  getClass()
        Class cl = test06.getClass();
        System.out.println(cl.getName());
        System.out.println(cl.getClass().getName());
        System.out.println("===================");

        System.out.println(test06.getClass());
        System.out.println(test06.getClass().getName());
        System.out.println("===============");

        //方法二 Class.forName()
        String s1="test.Test06";
        Class cl2 = Class.forName(s1);
        System.out.println(cl2);
        System.out.println(cl2.getName());
        System.out.println("===============");

        //方法三 int.class(类型.class)
        Class cl3 = int.class;
        System.out.println(cl3);
        System.out.println(cl3.getName());
        System.out.println("================");

        Class cl4 = Class.forName("test.Test06"); //获得Class类型对象实例
        //利用反射和无参构造器创建对象
        Test06 o1 = (Test06) cl4.getConstructor().newInstance();
        System.out.println(o1.a);

        //利用反射和有参构造器创建对象
        Test06 o2 = (Test06) cl4.getConstructor(int.class).newInstance(10);
        System.out.println(o2.a);
    }
}

2.获取类的属性与方法
//利用反射分析类的能力——检查类的结构
class ReflectionTest{
    private int a;
    protected int b;
    public int c;

    public ReflectionTest() {
    }

    public ReflectionTest(int a,int b,int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    private void t1(){
        System.out.println("ok");
    }

    public int getB(){
        return b;
    }

    public void setB(int b){
        this.b=b;
    }


    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException {

        Class rTestClass = ReflectionTest.class; //获取Class类型对象实例
        /*ReflectionTest reflectionTest = new ReflectionTest();
        Class aClass = reflectionTest.getClass();*/

        //1.利用反射获取对象字段描述
        Field[] fields = rTestClass.getFields(); //获取类所有公共字段,包括继承自超类的
        Field[] declaredFields = rTestClass.getDeclaredFields(); //获取类所有字段,包括私有的、受保护的,不包括超类的
        //Field a = rTestClass.getField("a");不能使用getField访问私有字段
        Field a = rTestClass.getDeclaredField("a"); //获取指定字段描述
        System.out.println(a+" "+"private修饰符描述值:"+a.getModifiers());
        Field b = rTestClass.getDeclaredField("b"); //获取指定字段描述
        System.out.println(b+" "+"protected修饰符描述值:"+b.getModifiers());
        Field c = rTestClass.getDeclaredField("c"); //获取指定字段描述
        System.out.println(c+" "+"public修饰符描述值:"+c.getModifiers());

        for (Field field : declaredFields) {
            System.out.println(field);
            System.out.println("字段的值:"+field.get(new ReflectionTest(7,8,9))); //获取指定对象中字段的值
            System.out.println("字段名:"+field.getName()); //getName()获得字段名
            //getModifiers()获得修饰符的描述返回值,isPrivate()分析返回值,判断修饰符
            System.out.println("字段修饰符是否为private:"+ Modifier.isPrivate(field.getModifiers()));
            System.out.println("字段类型:"+field.getType());
            System.out.println("是否为volatile修饰:"+Modifier.isVolatile(field.getModifiers()));
        }
        System.out.println("===============================");

        //2.利用反射获取对象方法描述
        Method[] methods = rTestClass.getMethods(); //获取类所有公共方法,包括继承自超类的
        Method[] declaredMethods = rTestClass.getDeclaredMethods(); //获取类所有方法,包括私有的、受保护的,不包括超类的
        Method setB = rTestClass.getDeclaredMethod("setB", int.class); //获取指定名方法
        System.out.println(setB);

        for (Method method : declaredMethods) {
            System.out.println(method);
            System.out.println("方法名:"+method.getName());
            System.out.println("方法访问修饰符值:"+method.getModifiers());
            System.out.println("是否为public:"+Modifier.isPublic(method.getModifiers()));
            System.out.println("方法参数类型:"+ Arrays.toString(method.getParameterTypes()));
            System.out.println("方法返回值类型:"+method.getReturnType());
        }
        System.out.println("=============================");

        //3.利用反射获取对象构造器描述
        Constructor[] constructors = rTestClass.getConstructors(); //获取类所有公共构造器
        Constructor[] declaredConstructors = rTestClass.getDeclaredConstructors(); //获取类所有的构造器
        Constructor constructor = rTestClass.getDeclaredConstructor(int.class, int.class, int.class); //获取指定参数类型的构造器描述
        System.out.println(constructor);

        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("构造器名称:"+declaredConstructor.getName());
            System.out.println("方法访问修饰符值:"+declaredConstructor.getModifiers());
            System.out.println("是否为public:"+Modifier.isPublic(declaredConstructor.getModifiers()));
            System.out.println("参数类型:"+Arrays.toString(declaredConstructor.getParameterTypes()));
        }

    }
}
3.利用反射动态操纵类对象
class MyTest{
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        //利用反射修改类
        //1.利用反射创建对象
        Class testClass = ReflectionTest.class;
        ReflectionTest test = (ReflectionTest) testClass.getConstructor(int.class, int.class, int.class).newInstance(10, 20, 30);
        System.out.println("b==>"+test.getB());
        System.out.println("=======================");

        //2.修改对象成员字段
        Field a1=testClass.getDeclaredField("a");
        a1.setAccessible(true);  //private字段需开启访问权限,否则会出现java.lang.IllegalAccessException异常

        Object v = a1.get(test);  //获取字段的值
        System.out.println("修改前的值:"+v);
        a1.set(test,50);
        System.out.println("修改后的值:"+a1.get(test));
        System.out.println("===================");

        //3.修改对象成员方法
        Method getB = testClass.getDeclaredMethod("getB");
        int invoke = (int) getB.invoke(test); //使用invoke执行方法
        System.out.println("b==>"+invoke);
        Method setB = testClass.getDeclaredMethod("setB", int.class);
        System.out.println("setB()返回值"+setB.invoke(test,60));  //设置方法参数值并执行方法
        System.out.println("执行方法后b==>"+getB.invoke(test));
        System.out.println("==============================");

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值