博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
String 类型的值能够被反射改变从而引发的意外事件
阅读量:6258 次
发布时间:2019-06-22

本文共 1408 字,大约阅读时间需要 4 分钟。

  • 今天刷技术文章,遇到了一个问题,用 Java 反射机制去修改 String 变量的值,出于深入研究,就发现了一个问题,即,用初始值比较修改后的值,用 == or .equals() 方法,出现了相等的情况

文字描述看起来比较难受,我们直接看代码

//创建字符串"Hello World", 并赋给引用 s        String s = "Hello World";        System.out.println("s = " + s); //Hello World        //获取String类中的value字段        Field valueFieldOfString = String.class.getDeclaredField("value");        //改变value属性的访问权限        valueFieldOfString.setAccessible(true);        //获取s对象上的value属性的值        byte[] value = (byte[]) valueFieldOfString.get(s);        //改变value所引用的数组中的第5个字符        value[5] = '_';        System.out.println("s = " + s);  //Hello_World        System.out.println("Hello World".toString());        System.out.println(s == "Hello World"); // true        System.out.println(s.equals("Hello World")); // true

如上方代码所示,我们定义了一个 String 变量 s ,并且赋值给它 "Hello World",然后通过 Java 的反射机制去修改第五个字符的值,在输出结果的时候,理所当然的结果是 "Hello_World",但是我在这个情况之上多了一手,把被修改后的值与初始值比较看看,会发生什么情况,结果一试就出现了问题,竟然与初始值相等且返回了 true .

于是,打算好好深究一下,我们知道 String 的变量是存放在 JVM 的常量池中的,同时指向 "Hello World" 的引用 s1 是 String 对象,存放在堆区,我们通过反射区修改的值并不是常量池中的 "Hello World" ,而是 堆区中的对象 s1 的值,所以我们输出 s1 的时候就是 "Hello_World" ,那么为什么初始值比较修改后的值的时候会出现 true 呢?

我们看看 System.out.println("Hello World".toString()); 这行代码,输出结果是 Hello_World,这是因为 "Hello World".toString() 的时候,会去常量池中去找 "Hello World"的引用,它的引用就是 s1 ,所以输出的是 s1 的值,即 "Hello_World",所以,到这里,我们就知道了,为什么 s == "Hello World" 和 s.equals("Hello World") 返回 true 了 .

[reference]

1011960-20180819153330707-702510555.png

1011960-20180819153402996-1366504800.png

转载地址:http://gunsa.baihongyu.com/

你可能感兴趣的文章
mysql安装问题 g++: not found
查看>>
Redis Keyspace Notifications
查看>>
linux|文件目录权限
查看>>
CentOS 6.8不重启在线增加硬盘
查看>>
Exchannge 2013数据库副本频繁自动切换
查看>>
设计一个不浪费水的热水器
查看>>
类的继承_子类继承父类
查看>>
CUDA实践指南(八)
查看>>
LockSupport
查看>>
DC之间的时间同步及组策略时间同步
查看>>
巅峰对决:水立方 即将上演3D版星际电竞
查看>>
网站需求量很大,服务器优化的tips
查看>>
Android EditText OnTouchListener事件重复
查看>>
单台centos机器启动多个vsftpd服务
查看>>
zabbix监控kafka
查看>>
谈谈linux2.6内核的驱动框架
查看>>
javascript节点的汇总
查看>>
windows计算机名大小写
查看>>
【JAVA】保龄球记分游戏
查看>>
mysql kernel: nf_conntrack version 0.5.0
查看>>