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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • NativeScaler()与loss_scaler

    NativeScaler()与loss_scaler源码:classNativeScaler:state_dict_key=”amp_scaler”def__init__(self):self._scaler=torch.cuda.amp.GradScaler()def__call__(self,loss,optimizer,clip_grad=None,clip_mode=’norm’,parameters=None,create_graph=False):

    2025年7月14日
    3
  • redis默认端口为什么是6379_redis 端口

    redis默认端口为什么是6379_redis 端口1、如果开了redis服务,先将服务关闭2、在window上找到redis的安装目录,修改redis.windows.conf文件,在里面将默认端口改为你想要的端口号3、将redis.windows.conf文件直接拖入redis-server.exe,弹出窗口

    2022年9月18日
    3
  • wp-login.php 404页面,wordpress404页面制作完整的正确操作流程

    wp-login.php 404页面,wordpress404页面制作完整的正确操作流程近期,看到很多SEO站长在我网站留言:为什么wordpress无法跳转正确的404页面或者404页面未找到?小L一查资料,看到搜索引擎出现的结果,有些很难让人操作和理解。于是,L氪迹SEO技术教程学习网在这里以图文形式来分享一下wordpress404页面制作完整的正确操作流程。【1、404页面模板下载】操作概述:小L在这里教大家较简单的方法,让你快速上线设置好404页面。打开你喜欢的网站的404…

    2022年7月27日
    15
  • idea2022.01永久激活码[最新免费获取]

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

    2022年4月2日
    210
  • Python 一行代码输出心形图案

    Python 一行代码输出心形图案Python3pythonprint('\n'.join([''.join([('Love'[(xy)%4]if((x0.05)2+(y0.

    2022年7月6日
    23
  • shell中find的用法_grep用法linux

    shell中find的用法_grep用法linuxfind命令的一般格式:findpathname-options[-exec]pathname是find命令所查找的目录路径-exec对匹配的文件执行该参数所给出的shell命令-options选项参数:-name按照文件名查找文件-perm按照文件权限来查找文件-user按照文件属主来

    2022年10月15日
    2

发表回复

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

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