繁体   English   中英

为什么数组不引用与字符串相同的对象?

[英]Why doesn't arrays reference to the same object as strings does?

如果在不使用“new”关键字的情况下声明它们,则对同一对象的字符串引用,如下所示:

String s1 = "Some string";
String s2 = "Some string";

System.out.println(s1 == s2); 
//prints true because 
//they reference to the same object

但是,与我的预期相反,这与数组不起作用:

char[] anArray = {'A', 'r', 'r', 'a', 'y'};
char[] oneArray = {'A', 'r', 'r', 'a', 'y'};
System.out.println("anArray == oneArray : " + (anArray == oneArray));
//prints false

我们没有明确提到它们是“新”数组,为什么它们不引用堆上的同一个对象呢?

因为数组与字符串不同,是可变的。 您通常不希望通过另一个变量引用的假定独立对象来更改从一个变量引用的对象。

char[] firstArray = {'A', 'r', 'r', 'a', 'y'};
char[] secondArray = {'A', 'r', 'r', 'a', 'y'};

firstArray[0] = 'X';
firstArray[1] = '-';

System.out.println(firstArray);
System.out.println(secondArray);

如果数组被“实例化”(即,如果相同的文字指向相同的实例),输出会是什么:

X-ray
X-ray

实际发生的事情:每个文字创建一个新实例:

X-ray
Array

我们没有明确提到它们是“新”数组,为什么它们不引用堆上的同一个对象呢?

这里真正的问题是:他们为什么会这样 如果在一般情况下,等效对象被JVM混淆,那将是一个真正的痛苦。 许多类都有可变实例; 这是一个有点问题,如果你有可变的情况下(和数组是可变的)和JVM将它们合并到单个实例没有你要求它。

所以通过扩展,真正的问题是:为什么你的s1s2引用同一个对象?

答案是:因为字符串是JDK和JVM特殊处理的特殊情况。 Java中的字符串被设计为在可能的情况下共享,以节省内存大小和流失,因此:

  1. 它们是不可变的(尽管如果你足够努力,你可以通过反射打破它),因此共享实例是可以接受的(因为你不会正式改变它们)。

  2. 字符串具有intern能力,将它们放入JVM管理的字符串池中。

  3. 字符串文字自动intern

如果不是#3,你的s1s2 就不会引用相同的字符串。 示例( 实时复制 ):

String s1 = "Some string";
int a = 1;
String s2 = (a == 1 ? "Some" : "Foo") + " string";
System.out.println("Same? " + (s1 == s2));
System.out.println("Equivalent? " + s1.equals(s2));

输出:

Same? false
Equivalent? true

由表达式生成并分配给该字符串s2不能自动intern版,所以它结束指的是不同势字符串对象。

如果您有一个具有不可变实例的类,您也可以为它们实现intern 字符串只是特殊之处在于它是由Java规范和运行时为我们完成的。

System.out.println(s1 == s2); 返回true只是因为我们有一个String常量池来检查这些文字(或实习的字符串)并重用相同的字符串。 数组从未为此设计过。

实际上:

String s1 = new String("Some string");
String s2 = new String("Some string");

将为System.out.println(s1 == s2);提供false System.out.println(s1 == s2);

java中的字符串保存在字符串表中。 当您创建两个完全相同的字符串时,它们将引用同一个对象。 如果你想知道字符串的值是否与另一个字符串相同,则必须执行String.Equals()。

由于数组未保存在数组表中,因此它们将引用不同的对象。 如果您想知道两个数组的内容是否相同,则必须使用String.Equals()通过数组进行迭代。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM