【问题标题】:String interned to two String objects but same behaviour and Value字符串实习到两个字符串对象,但行为和值相同
【发布时间】:2018-02-04 20:39:31
【问题描述】:

字符串是不可变的(事实)

假设我有下面给出的两个字符串对象:

String str1 = new String("dave");
String str2 = new String("dave");

在编译时,会发生字符串对象的实习。根据维基百科,它说“字符串实习是一种仅存储每个不同字符串值的副本的方法,该副本必须是不可变的。Java 中的所有编译时常量字符串都使用此方法自动实习。”

如果是这样,那么我的两个引用 str1 和 str2 会发生什么?编译后它们会指向哪个对象?

我希望它是有效的问题,否则请纠正我,我有点困惑。

【问题讨论】:

  • str1str2不是编译时间常数,因为它们都是用 new 实例化的
  • @khelwood,所以你的意思是这两个引用都会在编译时跳过实习。这两个相似的物体不会发生任何事情。它们将与各自的引用单独存在。是这样吗?
  • 两个字符串字面量"dave" 可以被interned,但是str1str2 持有的对象是new 在运行时创建的不同对象。它们确实单独存在。
  • 换句话说str1 != str2 && str2 != "dave", && str2 != "dave"
  • System.out.println(str1 == str2); 没有回答您的问题吗? new String("dave")"dave"相同。

标签: java string object reference immutability


【解决方案1】:

下面的 str1 和 str2 都是在堆上创建的,因为您是在运行时创建它们的。甚至这两个对象都是在不同的引用处创建的。

String str1 = new String("dave");
String str2 = new String("dave");

即使 str1 == str2 也会返回 false。它们的值相同,但它们是堆上的两个不同对象。


但是,如果您在编译时创建对象,例如

String str1="dave";
String str2="dave";

那么 str1 == str2 将返回 true,因为这两个对象都是 编译时在字符串池中创建的相同引用的一部分。

当我们使用双引号创建一个字符串时,它首先在字符串池中查找具有相同值的字符串,如果找到则返回引用,否则在池中创建一个新的字符串,然后返回引用。

【讨论】:

  • 你能看看我上面最后发表的评论吗?
  • 我想,我现在回答了你的问题。只需检查我更新的答案。编译时间和运行时间——这对于字符串对象来说是两件不同的事情。
  • “因为这两个对象都是同一个引用的一部分,而且是字符串文字池”..怎么样? str1 和 str2 是不同的引用并指向同一个对象..!!这就是为什么他们回归真实。我在问,这些是什么时候创建的?
  • 所以有什么不同,第二次没关系,我理解。但是第一次呢。所以要么我们写 String str = "dave 要么 String str = new String("dave"),两者都是同一个东西..NO ?
  • 说的有道理……!! :)
【解决方案2】:

通过使用new 运算符,您指定要创建新对象。 虽然我们知道 Java 中的 String 是不可变的,所以使用 new 运算符会花费您更多的时间和资源。
更好的选择是不使用 new 运算符来使用字符串池。

示例:

String str1="dave";
String str2="dave";

上面的代码将创建一个字符串对象,str1str2 都指的是 .
str1==str2 将返回true

有关更多信息,您可以阅读 Java 中的字符串池。

【讨论】:

  • 你能看看我上面最后发表的评论吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多