文档章节

反射机制中获取private成员的值

Lienson
 Lienson
发布于 03/28 17:38
字数 363
阅读 127
收藏 1

我们来看下例子:

@Data
public class Demo {

    public String name;
    private String title;

}

 

public class Test {

    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("com.lian.demo.Demo");
            Demo demo = (Demo) clazz.newInstance();
            demo.setName("name1");
            demo.setTitle("title1");

            Field[] fields = clazz.getDeclaredFields();
            Arrays.stream(fields).forEach(field -> {
                try {
                    System.out.println("成员变量"+field.getName()+"的值为:"+field.get(demo));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

执行结果如下:

成员变量name的值为:name1
java.lang.IllegalAccessException: Class com.lian.demo.Test can not access a member of class com.lian.demo.TestDemo 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.lian.demo.Test.lambda$main$0(Test.java:38)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
	at com.lian.demo.Test.main(Test.java:31)

说明反射机制中无法获取到private成员的值。那到底有没有办法获取到?当然是有。Java反射机制提供的setAccessible()方法可以取消Java的权限控制检查。

Arrays.stream(fields).forEach(field -> {
                boolean flag = field.isAccessible();
                System.out.println(field.getName() + ":" + flag);
                try {
                    //设置该属性总是可访问
                    field.setAccessible(true);
                    System.out.println("成员变量"+field.getName()+"的值为:"+field.get(demo));
                } catch (IllegalAccessException e) {
                    System.out.println(e.getMessage());
                }
                //还原可访问权限
                field.setAccessible(flag);
            });

这下没问题了,可以获取到了。setAccessible(true)取消了Java的权限控制检查,但不是改变方法或字段的访问权限。

而对于setAccessible()方法是否会破坏类的访问规则,产生安全隐患,我在知乎上面看到的一篇回答貌似很有道理:

 

 

© 著作权归作者所有

Lienson
粉丝 15
博文 107
码字总数 97577
作品 0
福州
程序员
私信 提问
Java反射机制的原理及在Android下的简单应用

花了几天时间,研究了一下Java的反射机制。在这里总结一下这几天学习的成果,一来分享自己的学习过程和在学习中遇到的问题,二来是给像我一样不太了解Java反射机制的同学做一个简单的介绍。在...

丁佳辉
2016/06/21
22
0
java 反射 :setAccessible

写框架大多要用上。在写框架时,大多要调用用户自定义的类,并生成对象,调用用户的方法。由于框架事前不知道用户的类,因此需要反射。反射的主要功能,当用户指定了类位置与类名,就能生成该...

swearyd457
2013/10/10
2.1K
0
Unity C#基础之 反射反射,程序员的快乐

反射反射,程序员的快乐 这句话想必大家都经常听过,基本上在绝大多数的框架和一些设计模式中都能看到反射的身影(MVC、IOC、AOP、O/RM), 反射:是.Net Framework提供的一个帮助类库,可以...

su9257_海澜
2018/02/14
0
0
JAVA高级编程之类加载-反射-动态代理

Java高级编程之类加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。 加载 就是指将class文件读入内存,并为之创建一个...

清枫_小天
2016/07/16
0
0
c#中的反射机制

反射的概述: 反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义...

云栖希望。
2017/12/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Ubuntu环境下安装PaddlePaddle

开篇 深度学习技术是目前非常热门的技术,笔者在闲暇之余决定学习一下这门技术,入门选择了百度开源的PaddlePaddle框架。 paddlepaddle介绍 飞桨(PaddlePaddle) 是国际领先的端到端开源深度学...

豫华商
49分钟前
3
0
LeetCode 第 287 号问题:寻找重复数,一道非常简单的数组遍历题,加上四个条件后感觉无从下手

今天分享的题目来源于 LeetCode 第 287 号问题:寻找重复数。 题目描述 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只...

五分钟学算法
今天
3
0
vuex mapActions

本文转载于:专业的前端网站➧vuex mapActions 在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在...

前端老手
今天
4
0
使用bash -x 调试信息查看lvextend -r的调用

--1.打开调试: [root@db01 storage]# set -x --2.执行命令: [root@db01 storage]# /usr/sbin/lvextend -r -L 710M /dev/shazam/storage + /usr/sbin/lvextend -r -L 710M /dev/shazam/sto......

突突突酱
今天
4
0
Linux重定向及反弹shell详解

这里说Linux重定向的原因主要还是为了详细了解一下Linux中的反弹shell 目录 0x01 文件描述符 0x02 重定向 0x03 反弹shell 0x04 交互重定向 0x05 命令变形 0x01 文件描述符 Linux的文件描述符...

无心的梦呓
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部