Ada*_*der 12 java string reflection
几乎所有人都知道Java中的字符串是不可变的.最近我发现了一些可能暗示它并不总是正确的东西.我们试试这段代码吧:
System.out.println("-------- BEFORE MODIFICATIONS --------");
String beforeTest = new String("Original");
System.out.println(beforeTest);
java.lang.reflect.Field valueField = String.class.getDeclaredField("value");
valueField.setAccessible(true);
valueField.set("Original", "Modified".toCharArray());
System.out.println("-------- AFTER MODIFICATIONS --------");
System.out.println(beforeTest);
System.out.println("Original");
String test = new String("Original");
System.out.println(test);
String test2 = new String("Original 2");
System.out.println(test2);
Run Code Online (Sandbox Code Playgroud)
输出将是:
-------- BEFORE MODIFICATIONS --------
Original
-------- AFTER MODIFICATIONS --------
Original
Modified
Modified
Original 2
Run Code Online (Sandbox Code Playgroud)
这个技巧如何运作?JVM如何知道应该更改哪些对象以及哪些对象不应该更改?这个伎俩的机制是什么?为什么已经创建的beforeTest字符串没有改变?这个技巧真的会贬低这个strings are immutable原则吗?
JB *_*zet 17
字符串文字被嵌入到池中.这意味着你写的时候
String s1 = "Foo";
String s2 = "Foo";
String s3 = new String("Foo");
Run Code Online (Sandbox Code Playgroud)
s1和s2引用相同的String对象,s3引用另一个,由另一个char数组支持.
在您的代码中,您通过修改包含"原始"字符串文字实例的字符的私有字符数组来违反String的不变量.但是因为beforeTest引用了另一个String实例,所以它没有被修改.
通过将字段保持私有到对象中,而不提供任何方法来修改此私有状态来实现不变性.通过使用反射,您可以破坏所有封装规则,从而可以违反不变性.
| 归档时间: |
|
| 查看次数: |
3805 次 |
| 最近记录: |