资讯专栏INFORMATION COLUMN

Java反射-私有属性和方法

Sleepy / 1127人阅读

摘要:尽管普遍认知是,实际可以通过反射访问其他类的私有属性和方法。这个特性在单元测试中特别有用。注意这只能在单体应用程序中运行,比如单元测试和常规程序。注意已经有很多关于禁用反射访问类私有属性的讨论。调用将关闭实例的访问权限检查,仅用于反射。

尽管普遍认知是,实际可以通过反射访问其他类的私有属性和方法。它甚至并不难。这个特性在单元测试中特别有用。本文将告诉你如何做。
注意:这只能在单体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

相关文章

  • Java 反射

    摘要:反射的使用通过反射获取构造方法并使用首先我们声明一个类方便我们进行介绍默认的构造方法默认的构造方法无参构造方法调用了公有无参构造方法执行了。。。 1.概述 1.1 什么是反射 java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 1...

    nodejh 评论0 收藏0
  • Java反射详细介绍

    摘要:通过反射获取带参无返回值成员方法并使用设置安全检查,访问私有构造函数必须创建实例这种不行,注意和方法需要传递参数测试复制这个功能获取私有方法,同样注意和的区别赋予访问权限调用方法。 反射 目录介绍 1.反射概述 1.1 反射概述 1.2 获取class文件对象的三种方式 1.3 反射常用的方法介绍 1.4 反射的定义 1.5 反射的组成 1.6 反射的作用有哪些 2.反射的...

    ingood 评论0 收藏0
  • Java反射

    摘要:中的反射反射能够分析类所拥有的能力的程序称为反射。获取类的名称获取类的修饰符获取类所在的包获取父类的属性获取类的构造器等等获得的构造器的使用获取构造器有两种方法。 Java中的反射 反射:能够分析类所拥有的能力的程序称为反射。 反射的作用 当我们在使用一个已有的类的时候,在主代码的main()方法中使用别的已有的类的时候,如果被使用的类发生了改变,那么导致我们的main()方法中...

    张红新 评论0 收藏0
  • 一文带你了解Java反射机制

    摘要:在的反射包中提供了三个类以及来分别描述属性方法和构造器。获取构造器获取方法可以看到我们可以通过一个类的对象很轻松的获取他的属性构造器以及方法信息。返冋一个用于描述构造器名的字符串。 想要获取更多文章可以访问我的博客 - 代码无止境。 上周上班的时候解决一个需求,需要将一批数据导出到Excel。本来公司的中间件组已经封装好了使用POI生成Excel的工具方法,但是无奈产品的需求里面有个合...

    darcrand 评论0 收藏0
  • 胖哥说反射 上卷

    摘要:可以通过提供的方法,获取对象,具体如下方法返回值方法名称方法说明返回一个指定参数的对象,该对象反映此对象所表示的类或接口的指定已声明方法。 我来学习反射 1.为什么我们要学习反射? 通过反射机制可以获取到一个类的完整信息,例如:所有(包含private修饰)属性和方法,包信息等。 换句话说,Class本身表示一个类的本身,通过Class可以完整获取一个类中的完整结构,包含此类中的方法定...

    hedzr 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<