在面试问题中,采访者问我
以下陈述之间的共同点和区别是什么:
String s = "Test";
String s = new String("Test");
内存分配有什么不同吗?
答案 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中。