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。

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • C++后端开发_用C开发网关

    C++后端开发_用C开发网关本文为博主2020年秋招提前批的c/c++后端开发面经整理,包括C/C++语言基础,计网,数据库,linux,操作系统,场景题,智力题和hr常问题。面试问题来自前人的工作和博主面试时遇到的值得记录的问题,其中面试题答案多为博主自行解答(并且面试的时候也基本是这样回答的),回答中都附上了参考资料的链接,全文共七万余字,仅供大家作为面试准备材料的参考。希望大家在准备面试的时候都能建立一个属于自己的题库,自己从网上寻找问题,然后自己进行解答,并且记录下来,这样在面试的时候就能行云流水般的回答上来。因此我把这份面

  • linux安装busybox教程

    linux安装busybox教程获取软件包下载busybox安装包1.31.0当前最新稳定版本,并解压:wgethttps://qqq-1253133144.cos.ap-chengdu.myqcloud.com/bbb/busybox-1.31.0.tar.bz2tar-xjvfbusybox-1.31.0.tar.bz2编译环境配置l编译和安装busybox:cdbusybox-1.31.0/makedefconfig&&makeinstallbusyb.

  • WinHTTP如何处理Cookie

    WinHTTP如何处理CookieCookieHandlinginWinHTTPHTTPsessiondataispassedbetweentheclientandserverinthecookieheaderoftherequestortheresponse.TheserversendscookiestotheclientintheSet-cookiehe

  • 前端使用Vue框架解决跨域问题「建议收藏」

    前端使用Vue框架解决跨域问题「建议收藏」现在项目开发,都实现前后端分离开发,导致前端向后端发送请求,会出现跨域错误;如何解决这个问题?方法一:后端可以下载cors包,对指定的前端域名允许请求;具体操作可以自行百度;今天主要介绍的是前端人员不用去麻烦后端人员,就可以通过前端设置实现跨域请求;方法二:前端设置服务器代理;本人用的是脚手架vue…

  • HTML中的window对象和document对象详解

    HTML中的window对象和document对象详解Window–代表浏览器中一个打开的窗口:对象属性  window//窗口自身  window.self//引用本窗户window=window.self  window.name//为窗口命名  window.defaultStatus//设定窗户状态栏信息  window.location//URL地址,配备布置这个属性可以打开新的页面对象方

  • 列存储中常用的数据压缩算法

    列存储中常用的数据压缩算法列存储,作为一种针对数据查询和数据分析设计的数据存储策略,在“大数据”越来越普及的今天可以说是相当地火热。相较于行存储,列存储的最大优势有二,其一就是查询涉及到数据库的哪几个列就读哪几个列,不读一点与查询不相关的列,大大减少了数据的读取,其二就是数据库数据分为多个独立的列来存储,相同数据类型的数据连续存储在一起,易于数据压缩,而这再次减少了数据的读取。以上正是列存储在处理数据查询和数据分析方面的天

发表回复

您的电子邮箱地址不会被公开。

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