#java 反射实现类外访问类的私有成员

java 专栏收录该内容
15 篇文章 0 订阅

java 用反射实现类外访问类的私有成员

学习本文需要提前掌握的知识:java类与对象

1、 思路分析

想要实现访问类的私有成员,我们有两个思路,一个是将私有成员转换成公有成员,另一个思路是在访问私有成员的时候绕过java语言检测

第一个思路,将私有成员转换成公有成员:这就和我们平常获取类的私有属性所用的方法一致——为这个私有成员写一个公有的get方法。

public void getInformation(){

    return 私有变量名;

}

public void carryFuntion(){

    私有方法;

}

像上面这样即可访问类的私有属性和方法,但这种方法需要在原类的基础上修改。来看下第二种方法,绕过java语言检测,这需要用到新的java知识——反射。

2、 java反射——另一种对象实现的方法

(1)、Class类:Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。

此类的部分相关方法:

forName(String className) //返回与带有给定字符串名的类或接口相关联的 Class 对象,className为所需类的完全限定名。

getConstructor() //获取当前对象的构造函数

getMethod(String name)  //获取此类的公有方法,name为方法名,后面可以放此方法的参数

getDeclaredMethod(String name)  //获取此类的所有方法,name为方法名,后面可以放此方法的参数

(2)、Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限

此类的部分相关方法:

newInstance()  //调用此对象的构造函数创建对象

(3)、Method类:提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。

此类的部分相关方法:

 //将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。
    mPrivate.setAccessible(Boolean flag); 
 //执行该方法,obj为从中调用底层方法的对象,args为用于方法调用的参数。
    invoke(Object obj, Object... args)

3、使用反射绕过java语言检测

首先创建一个对象

public class Try{

    private void privateTest(){

           System.out.println("这是role对象的私有方法");

    }

    public void publicTest(){

           System.out.println("这是role对象的公有方法");

    }

}

在主函数里写一个方法,先获取相关对象,然后获取其构造函数,执行构造函数创建对象,获取此对象的相关方法(如果该方法是非公有方法需要用getDeclaredMethod方法获取),非公有方法需要用setAccessible绕过java语言检测,最后执行这些方法即可。

public static void testMethod() throws Exception {

              // forName返回与带有给定字符串名的类或接口相关联的Class对象。

              Class s =
Class.forName("com.antony.inherit0726.Try");

              /*

               * 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。参数是 Class 对象的一个数组,这些

               * Class 对象按声明顺序标识构造方法的形参类型。

               */

              Constructor con = s.getConstructor();

              // 创建对象

              Object obj = con.newInstance(null);

              // 获取类的方法

              Method mPublic = s.getMethod("publicTest");

              // 可以获取所有方法

              Method mPrivate = s.getDeclaredMethod("privateTest");

              /*

               * 将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为false 则指示反射的对象应该实施 java语言访问检查。
               */

              mPrivate.setAccessible(true);

              // 调用方法

              mPublic.invoke(obj);

              mPrivate.invoke(obj);

       }
  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:创作都市 设计师:CSDN官方博客 返回首页

打赏作者

高山听流水

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值