这是我在面试中遇到的一个问题。
我定义了两个字符串,如下:
String s1="Java";
String s2="Java";
我的问题是这两个引用是否指向同一内存位置。通常情况下,当我们创建相同的字符串(没有使用new关键字),内容是否只被存储在内存中一次,所有具有相同内容的String对象都只是指向同一个位置,而不会多次存储字符串"Java"? s1和s2的哈希码是相同的。但哈希码是否直接依赖于对象的内存位置?
这是我在面试中遇到的一个问题。
我定义了两个字符串,如下:
String s1="Java";
String s2="Java";
我的问题是这两个引用是否指向同一内存位置。通常情况下,当我们创建相同的字符串(没有使用new关键字),内容是否只被存储在内存中一次,所有具有相同内容的String对象都只是指向同一个位置,而不会多次存储字符串"Java"? s1和s2的哈希码是相同的。但哈希码是否直接依赖于对象的内存位置?
toString()
方法的输出)除非该方法通过String.intern()
明确请求,否则不会被联接。是的,所有使用联接字符串的地方都将共享相同的内存位置 - 这是为什么首先要联接字符串的重要原因之一。
至于其他语言,这是一个更大的问题,但通过这些答案中的所有信息,我相信你可以在网上研究它。简而言之,没有普遍一致的意见认为应该如何做。
String s1="Java";
String s2="Java";
My question is whether these two references point to the same memory location
愚蠢的引用Java语言规范§3.10.5:
字符串字面量是对String类实例的引用(§4.3.1, §4.3.3)。
此外,字符串字面量总是引用同一个String类实例。这是因为字符串字面量 - 或者更一般地说,常量表达式的值为字符串(§15.28) - 被“内部化”以共享唯一实例,使用String.intern方法。
请阅读代码示例的注释:
此示例说明了六个要点:
在同一包(§7)中的同一类(§8)中的文字字符串表示对同一个String对象(§4.3.1)的引用。
在同一包中的不同类中的文字字符串表示对同一个String对象的引用。
在不同包中的不同类中的文字字符串也表示对同一个String对象的引用。
由常量表达式(§15.28)计算的字符串在编译时计算,然后被视为字面值。
在运行时通过连接计算的字符串是新创建的,因此是不同的。
显式地将计算字符串放入池中的结果是与具有相同内容的任何现有文字字符串相同的字符串。
当编译器优化您的字符串字面值时,它会看到s1和s2具有相同的值,因此您只需要一个字符串对象。这是安全的,因为Java中的字符串是不可变的。
String s1="Java";
String s2="Java";
System.out.println(s1== s2);
这个例子的结果是true
,因为s1
和s2
指向同一个对象。
字符串池是一种机制,所有已定义的字符串都存储在某个“池”中,在创建新的字符串对象之前,编译器会检查是否已经定义了这样的字符串。
示例。
第一个示例
String s1 = "FirstString";
String s2 = "FirstString";
if(s1 == s2) {
//This condition matched true because java don't make separate object for these two string. Both strings point to same reference.
}
String s1= "FirstString";
String s2 = new String("FirstString");
if(s1.equals(s2)) {
//This condition true because same content.
}
if(s1 == s2) {
//This condition will be false because in this java allocate separate reference for both of them
}
结论:Java 如何检查字符串是否存在。如果我们使用 new 创建了第二个字符串对象并且内容不同,则会创建一个新的对象并分配不同的引用,如果我们没有使用 new 创建对象并且内容相同,则会将相同的引用赋值给原先包含的第一个字符串。
new
,无论内容如何,你总会得到一个新的字符串对象。 - user207421当你拥有
String str1 = new String("BlaBla"); //In the heap!
String str2 = new String("BlaBla"); //In the heap!
如果你通过new
操作符(和构造函数)显式地创建了一个String
对象,那么你将会有每个对象指向一个不同的存储位置。
但是如果你有:
String str1 = "BlaBla";
String str2 = "BlaBla";
那么你就有了隐式构造。如果两个字符串字面值具有相同的值,则它们共享相同的存储空间,这是因为Java保留了相同字符串的存储!(具有相同值的字符串)
String s1="Java";
String s2="Java";
String s1 = "some";
String s2 = "some";
然后使用字符串池机制,引用s1和s2将指向具有值“some”的相同字符串对象。
String s1="Java";
String s2="Java";
两者指向同一对象。欲了解更多详细信息请点击此处
是的,Andrew Hare在这个链接https://dev59.com/ZXE95IYBdhLWcg3wCJbk#2486195上回答了。
基本上,字符串池允许运行时通过在池中保留不可变字符串来节省内存,以便应用程序的各个区域可以重用常见字符串的实例,而不是创建多个实例。