Java反射学习总结二(用反射调用对象的私有属性和方法)
大家都知道正常的调用是不可以访问对象的private修饰的属性和方法的,这也是Java的封装性原则。
但是有没有方法可以强制去访问对象的private修饰的属性和方法呢?那就是用反射!(这个可能在面试题中被问到哦)
接下来就来看看是如何实现的:
我们先去jdk里看一下描述属性的类Field,和方法的类Method:
Class Field
- java.lang.Object
- java.lang.reflect.AccessibleObject
- java.lang.reflect.Field
Class Method
- java.lang.Object
- java.lang.reflect.AccessibleObject
- java.lang.reflect.Method
可以看到这两个类有个共通的特点,就是他们都继承自java.lang.reflect.AccessibleObject这个类,我们好好看看这个类的描述
Class AccessibleObject
- java.lang.Object
- java.lang.reflect.AccessibleObject
- All Implemented Interfaces:
- AnnotatedElement
- Direct Known Subclasses:
- Constructor, Field, Method
public class AccessibleObject
extends Object
implements AnnotatedElementThe 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
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方法打印出来:
- public class Test2 {
- public static void main(String[] args) throws Exception {
- //获得Dog类的Class对象
- Class<?> classType = Class.forName("Dog");
- //生成对象的实例
- Object obj = classType.newInstance();
- //取得dogName属性
- Field dogName = classType.getDeclaredField("dogName");
- //禁止Field的访问控制检查
- dogName.setAccessible(true);
- //将Field的值设为“Xiao Qiang”
- dogName.set(obj, "Xiao Qiang");
- //取得say()方法
- Method say = classType.getDeclaredMethod("say", new Class[]{});
- //禁止say方法的访问控制检查
- say.setAccessible(true);
- //调用say方法
- say.invoke(obj, new Object[]{});
- }
- }
- class Dog {
- //私有的属性
- private String dogName = "Wang Cai";
- //私有的方法
- private void say() {
- System.out.println(dogName + ": Wang Wang");
- }
- }
输出结果:Xiao Qiang: Wang Wang
这里需要特别注意一个地方:
如果想用反射修改访问控制检查的话,获取Method和Field对象的时候一定要用getDeclaredField和getDeclaredMethod。不要用getField和getMethod。
虽然这两个方法的参数都是相同的,但不同点在于getMethod和getField只能获得public修饰的属性和方法。而getDeclared可以获取任何类型的属性和方法,因为这个例子要调用私有的属性和方法,所以要用getDeclaredXX。
Java反射学习总结二(用反射调用对象的私有属性和方法)的更多相关文章
- Java反射机制(三):调用对象的私有属性和方法
一. 通过反射调用类中的方法 在正常情况下,得到类的对象后,我们就可以直接调用类中的方法了,如果要想调用的话,则肯定必须清楚地知道要调用的方法是什么,之后通过Class类中的getMethod方法,可 ...
- 【Java语言特性学习之二】反射
一.概念java加载class文件分两种情况:(1)类型是编译器已知的,这种文件的.class文件在编译的时候,编译器会把.class文件打开(不加载)检查,称为Run- Time Type Iden ...
- Java多线程学习(二)synchronized关键字(2)
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java多线程学习(二)synchronized关键字(1)
转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...
- Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer
作者:Grey 原文地址:Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer ByteBuffer.allocate()与ByteBuffer.allocateD ...
- Java IO学习笔记二
Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...
- 2019/3/4 java集合学习(二)
java集合学习(二) 在学完ArrayList 和 LinkedList之后,基本已经掌握了最基本的java常用数据结构,但是为了提高程序的效率,还有很多种特点各异的数据结构等着我们去运用,类如可以 ...
- python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码
python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码 淘宝IP地址库 http://ip.taobao.com/目前提供的服务包括:1. 根据用户提供的 ...
- Java基础学习笔记(二) - 面向对象基础
面向对象 一.面向对象概述 面向对象思想就是在计算机程序设计过程中,参照现实事物,将事物的属性特征.行为特征抽象出来,描述成计算机时间的设计思想.面向对象思想区别于面向过程思想,强调的是通过调用对象的 ...
随机推荐
- jq--图片懒加载
html 1.给图片不给真真意义上的src属性路径,可通过我们自己想要添加时改变它的属性路径即可. 2.要获取浏览器中三种高度. $(window).height();//屏幕高度 $(window) ...
- 洛谷——P3178 [HAOI2015]树上操作
https://www.luogu.org/problem/show?pid=3178#sub 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 ...
- 通过OpenSSL解析X509证书基本项
在之前的文章"通过OpenSSL解码X509证书文件"里.讲述了怎样使用OpenSSL将证书文件解码,得到证书上下文结构体X509的方法. 以下我们接着讲述怎样通过证书上下文结构体 ...
- Python笔记---错误笔记
Python---错误笔记 1. Python编码问题: 我们在编写 Python 脚本时,往往会写上中文凝视. 可是有时候,当我们执行程序时.却发现例如以下错误:SyntaxError: Non-A ...
- softInputMode- 软件盘监听事件
软件盘的监听事件,如下 private final OnKeyListener mSubjectKeyListener = new OnKeyListener() { @Override public ...
- Android开发经验之在图片上随意点击移动文字
只要在图片范围之内,文字可随意点击移动. package xiaosi.GetTextImage; import android.content.Context; import android.con ...
- elasticsearch transport 请求发送和处理
前一篇分析对nettytransport的启动及连接,本篇主要分析transport请求的发送和处理过程.cluster中各个节点之间需要相互发送很多信息,如master检测其它节点是否存在,node ...
- GPU-Z:显卡体质、显卡各传感器实时状态的查看
1. TechPowerUp GPU-Z:查看显卡体质 下载地址:Download TechPowerUp GPU-Z | techPowerUp 点击 bus interface 后的?进行显卡的体 ...
- ELK之日志查询、收集与分析系统
项目由来 (1)开发人员不能登录线上服务器查看详细日志,经过运维周转费时费力 (2)日志数据分散在多个系统,难以查找与整合 (3)日志数据量巨大,查询速度太慢,无法满足需求 (4)无法全局掌控项目运行 ...
- make 2>&1 | tee build.log
make 2>&1 | tee build.log 保存编译log,方便问题查找