java中的基本反射回顾

11 篇文章 1 订阅

java中的基本反射回顾

想了解Hook技术反射永远是绕不过去的拦路虎,所以打算复习一下简单的java反射,仅以此文作为复习和熟悉markdown的语法。本文主要会涉及的反射实例如下

  • 反射类的私有属性
  • 反射类的私有方法
  • 反射类的私有构造方法
  • 反射内部类的私有属性
  • 反射内部类的私有方法
首先准备一个被反射的类

下面这个类包含了我们所有要反射的方法和属性

public class ReflectTest {

    private String pStr = "普通类的私有属性";

    public ReflectTest() {
    }

    private ReflectTest(String pStr) {
        this.pStr = pStr;
    }

    public void logPStr(){
        Log.e("TAG", "logPStr: ==========="+pStr );
    }

    private void priLogPStr(){
        Log.e("TAG", "priLogPStr: ==========="+pStr );
    }

    class PcText {
        private String pcStr = "内部类中的私有属性";

        private void showLog(){
            Log.e("TAG", "showLog: =========内部类中的私有方法" );
        }

    }

}
一.反射类的私有属性

方法

/**
     * 反射类的私有属性
     */
    private void reflectPrivateAttribute(){
        try {
            ReflectTest reflectTest = new ReflectTest();
            //装载要反射的类
            Class<?> aClass = Class.forName("com.example.hookdemoapp.ReflectTest");
            //通过getDeclaredField获取的属性包含所有修饰
            //如果用getField则只能获取public的属性
            Field field = aClass.getDeclaredField("pStr");
            //设置改属性可以被访问
            field.setAccessible(true);
            Log.e("TAG", "pStr: 1======================" +field.get(reflectTest));
            //set方法第一个参数为实例,第二个参数为属性的目标值
            field.set(reflectTest, "修改后的私有属性");
            Log.e("TAG", "pStr: 2======================" +field.get(reflectTest));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

执行结果如下,方法的注释写的很清楚,这里不在赘述。

E/TAG: pStr: 1======================普通类的私有属性
E/TAG: pStr: 2======================修改后的私有属性
二.反射类的私有方法

方法

/**
     * 反射类的私有方法
     */
    private void reflectPrivateConstructor(){
        try {
            ReflectTest reflectTest = new ReflectTest();
            //装载要反射的类
            Class<?> aClass = Class.forName("com.example.hookdemoapp.ReflectTest");
            //通过getDeclaredMethod获取的方法包含所有修饰
            //如果用getMethod则只能获取public的方法
            Method method = aClass.getDeclaredMethod("priLogPStr");
            //设置成可以被访问
            method.setAccessible(true);
            //invoke为执行方法,第一个参数是类的实例,后面的参数为方法的传参,没有参数可以传null
            method.invoke(reflectTest, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

执行结果如下

E/TAG: priLogPStr: ===========普通类的私有属性
三.反射类的私有构造方法

方法

    /**
     * 反射类的私有构造方法创建对象
     */
    private void reflectPrivateMethod(){
        try {
            //装载要反射的类
            Class<?> aClass = Class.forName("com.example.hookdemoapp.ReflectTest");
            //参数类型类的集合
            Class[] p = {String.class};
            //反射带有一个参数的构造方法
            Constructor<?> declaredConstructor1 = aClass.getDeclaredConstructor(p);
            declaredConstructor1.setAccessible(true);
            //传入参数创建对象
            Object obj = declaredConstructor1.newInstance("通过反射私有构造方法创建对象");
            //通过getDeclaredMethod获取的方法包含所有修饰
            //如果用getMethod则只能获取public的方法
            Method method = aClass.getDeclaredMethod("priLogPStr");
            //设置成可以被访问
            method.setAccessible(true);
            //invoke为执行方法,第一个参数是类的实例,后面的参数为方法的传参,没有参数可以传null
            method.invoke(obj, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

执行结果如下

priLogPStr: ===========通过反射私有构造方法创建对象
四.反射内部类的私有属性

方法

/**
     * 反射内部类的私有属性
     */
    private void reflectICPrivateAttribute(){
        try {
            ReflectTest reflectTest = new ReflectTest();
            //装载要反射的类,涉及内部类要用"类$内部类"的形式
            Class<?> aClass = Class.forName("com.example.hookdemoapp.ReflectTest$PcText");
            //反射内部类的无参构造时需要传入外部类的class
            Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(ReflectTest.class);
            declaredConstructor.setAccessible(true);
            //传入参数创建对象,这里为了方便参数没通过反射创建
            Object obj = declaredConstructor.newInstance(reflectTest);
            //通过getDeclaredField获取的属性包含所有修饰
            //如果用getField则只能获取public的属性
            Field field = aClass.getDeclaredField("pcStr");
            //设置成可以被访问
            field.setAccessible(true);
            Log.e("TAG", "reflectICPrivateAttribute: =================="+field.get(obj) );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

执行结果如下

E/TAG: reflectICPrivateAttribute: ==================内部类中的私有属性
五.反射内部类的私有方法

方法

/**
     * 反射内部类的私有方法
     */
    private void reflectICPrivateMethod(){
        try {
            ReflectTest reflectTest = new ReflectTest();
            //装载要反射的类,涉及内部类要用"类$内部类"的形式
            Class<?> aClass = Class.forName("com.example.hookdemoapp.ReflectTest$PcText");
            //反射内部类的无参构造时需要传入外部类的class
            Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(ReflectTest.class);
            declaredConstructor.setAccessible(true);
            //传入参数创建对象,这里为了方便参数没通过反射创建
            Object obj = declaredConstructor.newInstance(reflectTest);
            //通过getDeclaredMethod获取的方法包含所有修饰
            //如果用getMethod则只能获取public的方法
            Method method = aClass.getDeclaredMethod("showLog");
            //设置成可以被访问
            method.setAccessible(true);
            method.invoke(obj, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

执行结果如下

E/TAG: showLog: =========内部类中的私有方法
结语

简单的反射涉及的方法并不多,下一步主备温故一下动态代理相关内容以便于后面了解hook技术。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值