问题描述
我正在阅读一篇说明Java字符串的并非完全不变。但是,在文章修改字符串的示例代码中,它调用string.toUpperCase()。toCharArray(),它返回一个新字符串。那么,如果你调用toUpperCase(),那么通过更改字符串的过程的目的是什么?以下是代码:
I was reading an article that said that Java strings are not completely immutable. However, in the article's sample code that modifies the string, it makes a call to string.toUpperCase().toCharArray(), which returns a new string. So what's the purpose of going through the process of changing the string if you call toUpperCase() anyway? Here is the code:
public static void toUpperCase(String orig)
{
try
{
Field stringValue = String.class.getDeclaredField("value");
stringValue.setAccessible(true);
stringValue.set(orig, orig.toUpperCase().toCharArray());
}
catch (Exception ex){}
}
另外,我注意到string.toUpperCase()本身不起作用。它需要是string.toUpperCase()。toCharArray()。这有什么原因吗?
Also, I noticed that string.toUpperCase() by itself doesn't work. It needs to be string.toUpperCase().toCharArray(). Is there a reason for this?
推荐答案
他在做什么:
他正在获取一些他知道正确长度的字符数组(例如String的大写版本)并将其作为String的后备数组。 (支持数组在String类中称为 value
。)
为了说明你可以在那里放置任何char数组。
To illustrate that you could put any char array there you wanted.
字符串是不可变的,这可以避免不变性。当然,不建议这样做 - 永远。相反,如果他说注意,因为人们可能会对你的代码执行此操作,我不会感到惊讶。即使你认为你的东西是安全的,也可能不是!
String is immutable, and this allows you to circumvent the immutability. Of course, this is not recommended to do - EVER. On the contrary, I would not be surprised if he was saying "Watch out, because people could potentially do this to YOUR code. Even if you think your stuff is safe, it might not be!"
这涉及广泛的影响。不可变变量不再是不可变的。最终变量不再是最终变量。线程安全对象不再是线程安全的。您认为可以依赖的合同,您不能再这样做了。所有这些都是因为某个工程师在某个地方遇到了问题,他无法用正常手段修复,所以他深入研究解决问题。 不要'那个人'。
The implications of this are wide reaching. Immutable variables are no longer immutable. Final variables are no longer final. Thread safe objects are no longer thread safe. Contracts you thought you could rely upon, you can no longer do so. All because some engineer somewhere had a problem he couldn't fix with normal means, so he delves into reflection to solve it. Don't be 'that guy'.
您还会注意到现在如何更改该String的hashCode。所以,如果你从未计算过该String的hashCode,它仍然为0,所以你没事。另一方面,如果你计算了它,当你把它放在HashMap或HashSet中时,它将不会被检索。
You'll also note that how the hashCode for that String would now be changed. So, if you've never calculated the hashCode for that String, it's still 0 so you're okay. On the other hand, if you have calculated it, when you go to put it in a HashMap or HashSet, it won't be retrieved.
考虑以下内容: / p>
Consider the following:
import java.util.*;
import java.lang.reflect.*;
class HashTest {
/** Results:
C:\Documents and Settings\glowcoder\My Documents>java HashTest
Orig hash: -804322678
New value: STACKOVERFLOW
Contains orig: true
Contains copy: false
*/
public static void main(String[] args) throws Exception {
Set<String> set = new HashSet<String>();
String str = "StackOverflow";
System.out.println("Orig hash: " + str.hashCode());
set.add(str);
Field stringValue = String.class.getDeclaredField("value");
stringValue.setAccessible(true);
stringValue.set(str, str.toUpperCase().toCharArray()); //
System.out.println("New value: " + str);
String copy = new String(str); // force a copy
System.out.println("Contains orig: " + set.contains(str));
System.out.println("Contains copy: " + set.contains(copy));
}
}
我敢打赌他这样做作为对不良行为的警告,而不是显示酷的伎俩。
I would bet he is doing this as a warning against bad behavior rather than showing a 'cool' trick.
编辑:我找到了你所指的文章,以及它所基于的文章。最初的文章指出:这意味着如果另一个包中的一个类使用实习字符串摆弄,它会对你的程序造成严重破坏。这是件好事吗?(你不需要回答;-)我我认为这很清楚这是一个保护指南,而不是如何编码的建议。
I found the article you're referring to, and the article it is based on. The original article states: "This means that if a class in another package "fiddles" with an interned String, it can cause havoc in your program. Is this a good thing? (You don't need to answer ;-) " I think that makes it quite clear this is more of a protection guide than advice on how to code.
所以如果你只用一条信息离开这个线程,反思是危险的,不可靠的,不容小觑!
So if you walk away from this thread with only one piece of information, it is that reflection is dangerous, unreliable, and not to be trifled with!
这篇关于使用反射修改字符串的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!