String对象地址可能的问题?

时间:2013-10-22 22:14:02

标签: java string pointers

情况:女朋友的Java老师说以下陈述是等同的。同时,Java书推荐后一种形式。

String a = new String("Hi");

String b = "Hi";

然后a.equals(b),这个世界很好。

然而,我的Java文本和C知识严重告诉我,自a==b以及a.equals(b)后,如果a发生了更改(String中不太可能,但是如果它无论如何都会变异,因为它可能以某种方式传递地址,即使JVM也不会停止),那么b也将被更改。因此,假设b.equals("Hi")

可能是危险的

有什么见解? b的声明是否真的安全,或者只是在RAM上轻了很多?

我不是在问这是什么区别。我知道b可能引用了a中创建的同一个对象。

3 个答案:

答案 0 :(得分:3)

当你使用字符串时,字符串可以是interned,即: -

 String b = "Hi"; 

但是当你使用new String("Hi")时,你会得到一个新的字符串对象。

所以

String s1 = new String("hi");
String s2 = new String("hi");
System.out.println(s1 == s2);  // False
  

b的声明是否真的安全

正如我所说,当你使用字符串时,字符串可以是interned

  

实习字符串使一些字符串处理任务更具时间性   节省空间的代价是在字符串需要更多时间   创建或实习。不同的值存储在字符串实习生中   池。

答案 1 :(得分:2)

  

然而,我的Java文本和C知识严重告诉我,因为a == b以及a.equals(b),如果a被更改(不太可能在字符串中,但如果它无论如何变异,如同它可能以某种方式传递地址,即使JVM也不会停止)然后b也将被更改。因此,假设b.equals(“Hi”)可能是危险的。

绝对这是安全的情况,因为 String s无法变异。如果不使用JNI或一些特别标记的“不安全”API,就不可能“以某种方式传递地址甚至JVM也不会停止”,在这种情况下,你可以破坏一切,所有赌注都会被取消,这就是为什么那些API很少使用且非常谨慎。 (简而言之,对99.99%的Java程序来说,这不是一个问题。)

如果a == ba以及b是对可变对象的引用,那么改变a引用的对象将绝对会影响{ {1}}也是。但b s不可变,这就是为什么像String这样的实习文字是安全的。

答案 2 :(得分:0)

这些陈述并不等同。 a引用了另一个对象而不是b,因为你要求它(也就是你叫new)。 a==b将评估为false

a等于bab引用的对象无法更改。

你不能在Java中改变String。尝试这样做(使用JNI或其他)会让你陷入严重的麻烦。