Java反射学习总结二(用反射调用对象的私有属性和方法)

Java反射学习总结二(用反射调用对象的私有属性和方法)

大家好,又见面了,我是全栈君。

大家都知道正常的调用是不可以访问对象的private修饰的属性和方法的,这也是Java的封装性原则。

但是有没有方法可以强制去访问对象的private修饰的属性和方法呢?那就是用反射!(这个可能在面试题中被问到哦)

接下来就来看看是如何实现的:

我们先去jdk里看一下描述属性的类Field,和方法的类Method:

java.lang.reflect

Class Field

java.lang.reflect

Class Method


可以看到这两个类有个共通的特点,就是他们都继承自java.lang.reflect.AccessibleObject这个类,我们好好看看这个类的描述

java.lang.reflect

Class AccessibleObject

  • All Implemented Interfaces:

    AnnotatedElement
    Direct Known Subclasses:

    Constructor
    Field
    Method

    public class AccessibleObject
    extends Object
    implements AnnotatedElement
    The AccessibleObject class is the base class for Field, Method and Constructor objects. It provides the ability to flag a reflected object as suppressing default Java language access control checks when it is used. The access checks–for public, default (package) access, protected, and private members–are performed when Fields, Methods or Constructors are used to set or get fields, to invoke methods, or to create and initialize new instances of classes, respectively.

大致意思就是:

这个AccessibleObject类是Field, Method and Constructor对象的一个父类,他可以让一个反射对象去禁止Java语言的访问控制检测。控制检测有public, default (package) access, protected, and private。。。blah blah blah。。。

这里我贴出控制访问控制检测的这个方法:(这个类里还有一些相关的方法,有兴趣的大家可以自己去看看)

 

setAccessible

public void setAccessible(boolean flag)
                   throws SecurityException
Set the 
accessible flag for this object to the indicated boolean value. A value of 
true indicates that the reflected object should suppress Java language access checking when it is used. A value of 
falseindicates that the reflected object should enforce Java language access checks.

大致意思:

设置标志去指示对象的boolean值,如果是true则禁止java访问控制检查,如果是false则强制反射对象使用java访问控制检查

知道了这个方法就可以做一个小例子测试一下啦。

下面这个例子很简单,就是定义一个dog类,里面有个private的属性dogName,和private的方法say。

main函数里用反射先去修改dogName,然后在调用say方法打印出来:

  1. public class Test2 {  
  2.   
  3.     public static void main(String[] args) throws Exception {  
  4.         //获得Dog类的Class对象  
  5.         Class<?> classType = Class.forName(“Dog”);  
  6.         //生成对象的实例  
  7.         Object obj = classType.newInstance();  
  8.           
  9.         //取得dogName属性  
  10.         Field dogName = classType.getDeclaredField(“dogName”);  
  11.         //禁止Field的访问控制检查  
  12.         dogName.setAccessible(true);  
  13.         //将Field的值设为“Xiao Qiang”  
  14.         dogName.set(obj, “Xiao Qiang”);  
  15.           
  16.         //取得say()方法  
  17.         Method say = classType.getDeclaredMethod(“say”, new Class[]{});  
  18.         //禁止say方法的访问控制检查  
  19.         say.setAccessible(true);  
  20.         //调用say方法  
  21.         say.invoke(obj, new Object[]{});  
  22.     }  
  23.   
  24. }  
  25.   
  26.  class Dog {  
  27.     //私有的属性  
  28.     private String dogName = “Wang Cai”;  
  29.     //私有的方法  
  30.     private void say() {  
  31.         System.out.println(dogName + “: Wang Wang”);  
  32.     }  
  33. }  

输出结果:Xiao Qiang: Wang Wang

这里需要特别注意一个地方:

如果想用反射修改访问控制检查的话,获取Method和Field对象的时候一定要用getDeclaredField和getDeclaredMethod。不要用getField和getMethod。

虽然这两个方法的参数都是相同的,但不同点在于getMethod和getField只能获得public修饰的属性和方法。而getDeclared可以获取任何类型的属性和方法,因为这个例子要调用私有的属性和方法,所以要用getDeclaredXX。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108659.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 阿里云ECSserver部署django

    阿里云ECSserver部署django

    2022年1月8日
    85
  • Java异常类型及处理

    Java异常类型及处理前言:Java异常,大家都很熟悉。但是对于具体怎么分类的,JVM对其怎么处理的,代码中怎么处理的,应该怎么使用,底层怎么实现的等等,可能就会有些不是那么清晰。本文基于此详细捋一下异常类型,实现以及使用时应怎么注意。一、异常实现及分类1.先看下异常类的结构图上图可以简单展示一下异常类实现结构图,当然上图不是所有的异常,用户自己也可以自定义异常实现。上图已经足够帮我们解释和理解异常…

    2022年5月19日
    37
  • 竞争性需求分析

    竞争性需求分析

    2021年11月18日
    48
  • nvcat premium 15 激活码_在线激活

    (nvcat premium 15 激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月27日
    110
  • Sql实现Split

    Sql实现Split

    2021年7月30日
    84
  • linux清除隐藏的挖矿程序

    linux清除隐藏的挖矿程序1.找出cpu高的程序,top找不到的话,用下面命令ps-aux–sort=-pcpu|head-102.杀掉相关进程kill-9pid3.查看crontab是否有定时任务4.删除相关命令[root@dbserverlib]#lsattrlibiacpkmn.so.3—-i——–e–libiacpkmn.so.3[root@dbserverlib]#chattr-ilibiacpkmn.so.3[root@dbserver

    2022年6月16日
    33

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号