分配和创建字符串实例之间有什么区别?

时间:2010-02-01 06:34:07

标签: java string memory

在面试问题中,采访者问我

以下陈述之间的共同点和区别是什么:

String s = "Test";

String s = new String("Test");

内存分配有什么不同吗?

6 个答案:

答案 0 :(得分:9)

String s = "Test"; 

首先在字符串常量池中查找String“Test”。如果发现s将被引用以找到找到的对象。如果未找到,则创建一个新的String对象,将其添加到池中,并使s引用新创建的对象。

String s = new String("Test");

首先会创建一个新的字符串对象并让它引用它。此外,字符串“Test”的条目在字符串常量池中生成,如果它尚未存在。

因此假设字符串“Test”不在池中,第一个声明将创建一个对象,而第二个声明将创建两个对象。

答案 1 :(得分:5)

记忆术语的不同之处在于形式的表达式: String s = "test"使用“interned”字符串以共享唯一的实例。

表格的调用:String s = "test"
String s = new String("test")

相比是有效的

第一个调用使用现有的常量表达式(如果有的话), 第二个调用创建一个新实例,而不使用任何现有实例。

下面的代码块说明了这一点:

String test = new String("test");
String internTest = "test";
String nonInternTest = new String("test");

System.out.println(test == internTest); // prints false
System.out.println(test != nonInternTest); // prints true
System.out.println(test.equals(nonInternTest)); // prints true

String test = new String("test"); String internTest = "test"; String nonInternTest = new String("test"); System.out.println(test == internTest); // prints false System.out.println(test != nonInternTest); // prints true System.out.println(test.equals(nonInternTest)); // prints true

另请注意,JLS指定了行为:
每个字符串文字都是对String类实例的引用(第4.3.3节)。 String对象具有常量值。字符串文字 - 或者更常见的是,作为常量表达式值的字符串是“实例化”,以便使用String.intern方法共享唯一实例。

答案 2 :(得分:1)

String s =“Test”; //创建一个String对象和一个引用变量 在这个简单的例子中,“Test”将进入池中,s将引用它。

String s = new String(“Test”); //创建两个对象和一个引用变量 在这种情况下,因为我们使用了new关键字,Java将创建一个新的String对象 在普通(非池)内存中,s将引用它。另外,文字“测试”会 放在游泳池里。

但它们的共同点是它们都创建了一个新的String对象,带有 “测试”的值,并将其分配给参考变量s。

答案 3 :(得分:0)

第一个将在String池中搜索字符串文字“Test”,如果它存在则s将引用它并且不会创建新的。并且仅当“Test”文字不存在时才创建新对象。

但是在第二种情况下,它会创建另一个对象而不必担心它是否存在。

答案 4 :(得分:0)

+创建一个新的String对象和创建引用之间的差异是什么,但我们告诉jvm创建一个新对象。 并创建refence意味着我们只创建自己的对象。

答案 5 :(得分:0)

String s=new String("Test")     

在这种情况下,将在堆区域中创建2个对象,而在scp(字符串常量池)中创建另一个对象,并且s始终指向堆Object。

String s ="Test";

在这种情况下,将仅在scp中创建1个对象,并且s始终指向该对象

注意
1. scp中的对象创建是可选的,首先它将检查scp中是否存在任何带有所需内容的对象(如果已存在对象),然后如果对象尚不可用,则将重用现有对象,然后仅创建一个新对象。但这仅适用于scp,不适用于堆。

2。垃圾收集器不允许访问SCP区域,因此,即使对象不包含引用变量,只要它存在于scp区域中,它也有资格使用GC

jvm关闭时,所有scp对象将自动销毁。

示例2;

String s1=new String("Test");
String s4=new String("Test");
     String s2="Test";
     String s3="Test";

注意:
每当我们使用强制性的新运算符时,都会在堆区域中创建一个新对象,因此,可能有两个现有对象在堆区域中具有相同的内容,而在scp中却没有,也就是说,在堆区域中可能存在重复的对象,但不是在scp中。