摘要:尽管普遍认知是,实际可以通过反射访问其他类的私有属性和方法。这个特性在单元测试中特别有用。注意这只能在单体应用程序中运行,比如单元测试和常规程序。注意已经有很多关于禁用反射访问类私有属性的讨论。调用将关闭实例的访问权限检查,仅用于反射。
尽管普遍认知是,实际可以通过反射访问其他类的私有属性和方法。它甚至并不难。这个特性在单元测试中特别有用。本文将告诉你如何做。
注意:这只能在单体Java应用程序中运行,比如单元测试和常规程序。如果你尝试在Java Applet程序中使用,可能需要注意SecurityManager问题。但是,你并不常做这些操作,并且到目前为止已偏离了本文主题。
注意:已经有很多关于Java9禁用反射访问类私有属性的讨论。根据我的经历,在Java9依旧是可以的(访问类私有属性),但这可能会在Java未来版本中改变。
访问私有属性需要调用Class.getDeclaredField(String name)或者Class.getDeclaredFields()方法。方法Class.getField(String name) 和Class.getFields()只返回类的public方法,所以不能使用它们。下面的示例代码是一个有私有属性的类,再下一个是通过反射访问私有属性。
public class PrivateObject { private String privateString = null; public PrivateObject(String privateString) { this.privateString = privateString; } }
PrivateObject privateObject = new PrivateObject("The Private Value"); Field privateStringField = PrivateObject.class. getDeclaredField("privateString"); privateStringField.setAccessible(true); String fieldValue = (String) privateStringField.get(privateObject); System.out.println("fieldValue = " + fieldValue);
示例代码会输出“fieldValue = The Private Value”,它是PrivateObject实例的privateString属性的值。
使用方法privateObject.class.getDeclaredField("privateString")时需要注意。这个方法返回私有属性。这个方法只返回特定类定义的属性,不包括任何超类的属性。
另外需要注意代码privateStringField.setAccessible(true);。调用这个方法将为特定的Field实例关闭访问权限检查,仅用于反射。现在你可以访问属性,不管它是private, protected 或者package scope,即使调用方不在访问scope内。你依旧不能使用普通代码访问私有属性,Java编译通不过。
访问类私有方法需要调用Class.getDeclaredMethod(String name, Class[] parameterTypes)或者Class.getDeclaredMethods()。方法Class.getMethod(String name, Class[] parameterTypes)和Class.getMethods() 只返回类的public方法,所以不能使用。下面是一个有私有方法的类和如何通过反射调用该类方法的私有代码:
public class PrivateObject { private String privateString = null; public PrivateObject(String privateString) { this.privateString = privateString; } private String getPrivateString(){ return this.privateString; } }
PrivateObject privateObject = new PrivateObject("The Private Value"); Method privateStringMethod = PrivateObject.class. getDeclaredMethod("getPrivateString", null); privateStringMethod.setAccessible(true); String returnValue = (String) privateStringMethod.invoke(privateObject, null); System.out.println("returnValue = " + returnValue);
示例代码会输出"returnValue = The Private Value",这是实例PrivateObject中的方法getPrivateString()的返回值。
注意,代码PrivateObject.class.getDeclaredMethod("privateString")。这个方法调用将返回类的私有方法。这个方法只返回类直接定义的方法,而不返回任何超类的方法。
另外需要注意代码privateStringMethod.setAccessible(true);。调用Method.setAcessible(true)将关闭Method实例的访问权限检查,仅用于反射。现在你可以调用方法,不论它是private, protected 或 package scope,即使调用者不在这些scopes内。你依旧不能通过普通方法访问类的私有方法,这会编译不通过。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/77339.html
摘要:通过反射获取带参无返回值成员方法并使用设置安全检查,访问私有构造函数必须创建实例这种不行,注意和方法需要传递参数测试复制这个功能获取私有方法,同样注意和的区别赋予访问权限调用方法。 反射 目录介绍 1.反射概述 1.1 反射概述 1.2 获取class文件对象的三种方式 1.3 反射常用的方法介绍 1.4 反射的定义 1.5 反射的组成 1.6 反射的作用有哪些 2.反射的...
摘要:在的反射包中提供了三个类以及来分别描述属性方法和构造器。获取构造器获取方法可以看到我们可以通过一个类的对象很轻松的获取他的属性构造器以及方法信息。返冋一个用于描述构造器名的字符串。 想要获取更多文章可以访问我的博客 - 代码无止境。 上周上班的时候解决一个需求,需要将一批数据导出到Excel。本来公司的中间件组已经封装好了使用POI生成Excel的工具方法,但是无奈产品的需求里面有个合...
阅读 3938·2023-04-26 01:48
阅读 3215·2021-10-13 09:40
阅读 1676·2021-09-26 09:55
阅读 3550·2021-08-12 13:23
阅读 1646·2021-07-25 21:37
阅读 3368·2019-08-30 15:53
阅读 1316·2019-08-29 14:16
阅读 1335·2019-08-29 12:59