Accessable属性是继承自AccessibleObject 类. 功能是启用或禁用安全检查
在反射对象中设置 accessible 标志允许具有足够特权的复杂应用程序(比如 Java Object Serialization 或其他持久性机制)以某种通常禁止使用的方式来操作对象。
setAccessible
public void setAccessible(boolean flag)
throws SecurityException

将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。

setAccessible方法是干什么用的呢让我们来看一段代码吧

public class User {private String name;public User(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

测试:

import java.lang.reflect.Field;public class Demo {public static void main(String[] args) throws Exception {  Class clazz = User.class;User u = new User("小明");for (Field f : clazz.getDeclaredFields()) {  System.out.println(f.isAccessible());//这里的结果是falsef.setAccessible(true);System.out.println(f.getName()+":"+f.get(u));}  }
}

通过运行以上代码,我们发现 System.out.println(f.isAccessible())这一句打印结果是"false",从字面上理解是说该字段不能被访问,但是为了保险起见我们还是去看一下源代码(Java有的时候就是比较坑,不一定能够见名知意,我们还是保险点比较好,虽然不算是做学问,但是学习的态度还是一丝不苟比较好),首先我们去掉f.setAccessible(true);

然后在 System.out.println(f.getName()+":"+f.get(u));这行打断点,但是发现不了问题,经过检查发现getName()这个方法并不抛异常,也就是是就算没有加f.setAccessible(true);

也可以获得name,抛异常的是f.get(u);这句话,我找到Field中的get(Object obj)方法,发现有这么一句

if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
}
}

这里的override就是我们用setAccessible设置的值,但是接下来就坑爹了Reflection以及其他几个类的源码不在jdk自带的源码中,找了半天才找到sun的源代码,导入源代码(最好将sun的源代码和java的放在一个文件夹里,不然一次只能导入一个源代码,要来回切换,比较麻烦)

然后我们debug定位到了Reflection类的ensureMemberAccess方法如图:

图中有一个verifyMemberAccess方法,这就是抛出异常的方法,进入该方法直接到了 boolean successSoFar = false;然后就return false了,因此抛出了IllegalAccessException异常,也就是说我们得出结论当isAccessible()的结果是false时不允许通过反射访问该字段

结论:当isAccessible()的结果是false时不允许通过反射访问该字段

实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问,一般情况下,我们并不能对类的私有字段进行操作,利用反射也不例外,但有的时候,例如要序列化的时候,我们又必须有能力去处理这些字段,这时候,我们就需要调用AccessibleObject上的setAccessible()方法来允许这种访问,而由于反射类中的Field,Method和Constructor继承自AccessibleObject,因此,通过在这些类上调用setAccessible()方法,我们可以实现对这些字段的操作。但有的时候这将会成为一个安全隐患,为此,我们可以启用java.security.manager来判断程序是否具有调用setAccessible()的权限。默认情况下,内核API和扩展目录的代码具有该权限,而类路径或通过URLClassLoader加载的应用程序不拥有此权限。例如:当我们以这种方式来执行上述程序时将会抛出异常

java.lang.IllegalAccessException: Class com.example.xj.myapplication.TestField can not access a member of class com.example.xj.myapplication.Student with modifiers "private"at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)at java.lang.reflect.Field.get(Field.java:390)at com.example.xj.myapplication.TestField.main(TestField.java:20)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

所以 f.setAccessible(true);得作用就是让我们在用反射时访问私有变量

field.setAccessible(true)相关推荐

  1. 反射避开field.setAccessible(true); field.set(t, lineArray[i]); 赋值

    Reflection should not be used to increase accessibility of classes, methods, or fields public <T& ...

  2. 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】...

    方法1:通过get()方法获取属性值 package com.sxd.test.controller;public class FirstCa{private Integer num;private ...

  3. java 反射(二)之提高反射的方法 setAccessible(true)

    setAccessible(true/false):表示启用和禁用安全检查的开关. 当值为true时,指反射对象在使用时应该取消java语言访问检查,值为false则只是反射的对象应该试试java语言 ...

  4. 【Elasticsearch】Fielddata is disabled on text field fielddata=true

    文章目录 1.概述 2.默认禁用 本文为博主九师兄(QQ:541711153 欢迎来探讨技术)原创文章,未经允许博主不允许转载. 1.概述 转载并且补充:https://www.cnblogs.com ...

  5. java 反射field_Java基础--反射之Field

    一.Field (1)Field /** * Field: 分装了字段的信息 * 1. 获取字段 * 1.1 Field[] fields = clazz.getDeclaredFields(); * ...

  6. java 反射 Constructor、Method、Field 基本用法

    java反射主要从以下几个方面理解 理解 Class 类 理解 Java 的类加载机制 学会使用 ClassLoader 进行类加载 理解反射的机制 掌握 Constructor.Method.Fie ...

  7. java反射 修改静态方法的值 setAccessible

    转载自 java反射 修改静态方法的值 setAccessible 这几天闲来无事.在网上看了一个题目,相信大家都知道这个题目 static void change(String str){str=& ...

  8. java根据field名获取变量_Java反射有多强?这5大神奇功能,你需要了解!

    点击上方"蓝字",关注了解更多 什么是反射? 在Java中,对于任意一个运行中的对象,可以调用该对象的任意属性和方法:已知一个类,可以获取这个类的所有属性和方法,这就是反射机制. ...

  9. Java反射使用的Field类介绍

    一.Field类的作用 Field是一个类,位于java.lang.reflect包下.在Java反射中Field类描述的是类的属性信息,功能包括 (1)获取当前对象的成员变量的类型 (2)对成员变量 ...

最新文章

  1. AngularJS自定义表单验证
  2. 现代软件工程 第十四章 【质量保障】 练习与讨论
  3. 基于visual Studio2013解决面试题之0410计算二进制中1的个数
  4. go | vscode远程调试linux服务器开发
  5. Windows下启动Apache报错:ServerRoot must be a valid directory
  6. 【RobotStudio学习笔记】(九)坐标偏移设置
  7. linux选择内核命令,Lenky个人站点
  8. Spring依赖注入@Autowired原理解析(一)之寻找需要注入的属性
  9. windows10桌面_三大虚拟桌面软件对比,总有一款适合你!
  10. php如何实现快速压缩视频,如何把大视频压缩小 怎么将视频压缩到最小方便储存...
  11. 小白学习MySQL - 一次慢SQL的定位
  12. 《Kubernetes知识篇:基于Namespace(多租户)进行资源配额管理》
  13. 验证网站代码的免费在线工具
  14. Wirecast Pro 12.1.0 中文特别版 Mac 多机位的现场网络视频直播工具
  15. linux防火墙关了端口还是不通,为什么linux防火墙关了 端口不通
  16. 电脑风扇控制软件-全网最全教程+下载链接
  17. SaaS、PaaS、IaaS、aPaaS、iPaaS、RaaS、RPAaaS,傻傻分不清楚?
  18. 接口测试-dubbo泛化调用
  19. 计算机网络技术实训自我评价,计算机网络技术个人简历自我评价范文
  20. 【流量池】BD跨界营销(6)

热门文章

  1. 程序员的健康作息时间 该看看啊
  2. 关于风筝的名人名言范文
  3. Vue使用UEditor百度编辑器,上传图片服务配置问题,查看版本
  4. 【2019-总结】初中毕业暑假集训No.6
  5. 【数学建模-某肿瘤疾病诊疗的经济学分析】数据分析
  6. linux发布java程序docker(一)
  7. java-php-net-python-东软校园医疗计算机毕业设计程序
  8. weblogic mysql 测试连接表_Weblogic数据库连接池配置
  9. ~这些年,我们一起学过的Java~04~接口与抽象类
  10. 耳机什么牌子音质好?音质最好的耳机排名