首页 > 试题广场 >

下面这条语句一共创建了多少个对象:String s="wel

[单选题]
下面这条语句一共创建了多少个对象:String s="welcome"+"to"+360;
  • 1
  • 2
  • 3
  • 4
String test="javaandpython"; 
String str1="java"; 
String str2="and"; 
String str3="python"; 
System. out. println(test=="java"+"and"+"python"): 
System. out. println(test ==str1 + str2 + str3);
对于上面这段代码,结果是true false
这是因为字符串字面量拼接操作是在Java编译器编译期间就执行了,也就是说编译器编译时,直接把"java"、"and"和"python"这三个字面量进行"+"操作得到一个"javaandpython" 常量,并且直接将这个常量放入字符串池中,这样做实际上是一种优化,将3个字面量合成一个,避免了创建多余的字符串对象(只有一个对象"javaandpython",在字符串常量池中)。而字符串引用的"+"运算是在Java运行期间执行的,即str1 + str2 + str3在程序执行期间才会进行计算,它会在堆内存中重新创建一个拼接后的字符串对象。且在字符串常量池中也会有str1,str2与str3,这里创建多少个新的对象与原来字符串常量池中有没有str1\str2\str3有关,如果之前存在就不会创建新的对象。
总结来说就是:字面量"+"拼接是在编译期间进行的,拼接后的字符串存放在字符串池中;而字符串引用的"+"拼接运算实在运行时进行的,新创建的字符串存放在堆中。
那么再来看这题,很明显只在编译期间在字符串常量池中创建了"welcometo360"一个字符串
发表于 2019-11-28 01:04:01 回复(30)
是否大家有没有刷到这类面试题:在执行String s = "Hello";s = s + " world!";这两行代码后,原始的String对象中的内容到底变了没有?
答案的解析:

没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 "Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。

通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫sString引用变量进行初始化,把它设置为初始值,应当这样做:
public class Demo {
       private String s;
              ...
       public Demo {
              s = "Initial Value";
       }
       ...
}
而非
s = new String("Initial Value");

后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。

上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。

至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即 StringBuffer。
说说我的看法:字面量的创建是发生在编译期,类似于上述面试题,答案只创建一个对象。
发表于 2019-09-03 11:27:01 回复(16)
使用Java Decompiler打开生成的class文件
public class hello
{
  public static void main(String[] paramArrayOfString)
  {
    String str = "helloto360";
  }
}
可以看出,在编译阶段已经将各个字段拼接成一个字符串,由于当前内存中没有该拼接的字符串,所以会动态生成一个对象,内容是拼接后的字符串。
发表于 2019-09-14 09:49:21 回复(4)
String在初始化时连接的全是常量,故只有一个String对象。
发表于 2018-12-21 17:43:56 回复(1)
发表于 2019-08-19 15:14:42 回复(5)
这题不严谨啊,如果常量池中原本没有“welcome”和“to”这两个常量对象,那就会创建这两个对象,但是有了就只会用已有的对象所以这题应该是1个或者3个对象啊
发表于 2020-01-17 13:56:09 回复(10)
String s = “a” + “b” + “c” + 360;编译器将其优化为String s = “abc360”,若常量池中不存在这个字符串则会常量池中创建一个对象,若存在则不创建
发表于 2019-10-15 09:28:26 回复(1)
这题有问题吧,首先字符串 S 是肯定会创建的,其他的会在常量池里找,例如有welcome,又就直接用,没有就创建一个,to也同理,还生成一个welcome to 360对象放在常量池,S指向welcome to 360,不知道常量池里有还是没有,所以有多种可能
发表于 2019-08-20 15:54:07 回复(9)
字面量"+"拼接是在编译期间进行的,拼接后的字符串存放在字符串池中;而字符串引用的"+"拼接运算实在运行时进行的,新创建的字符串存放在堆中。
发表于 2021-11-07 13:13:25 回复(1)
个人认为编译器会进行优化为:String s="welcometo360";,然后对象不是new出来的,s直接指向常量池的地址。
发表于 2019-10-18 08:40:28 回复(1)
全是常量的字符串在编译时会进行优化,也就是 说编译器会将你写的语句优化成 String s =“welcometo360”
发表于 2022-02-24 19:03:47 回复(0)
答案错了,正确答案应该是0或1,没有判断常量池是否已经存在。 编译器优化成了String s = "welcometo360"; 编译器优化部分请自行javap
可以通过下面这段代码验证常量池jdk1.7/1.8运行下面这段代码
public static void main(String[] args) {         char[] dd = {'d','d'};         String s = new String(dd);         System.out.println(s.intern()==s);         String s1 =new String("ff");         System.out.println(s1.intern() == s1);         String k = "ff"+"to"+360;         System.out.println(k.intern()==k); }





编辑于 2020-11-10 15:01:18 回复(0)
不是说String拼接有新对象吗
发表于 2019-08-31 22:03:57 回复(2)
补充:
String a="java"  创建了一个对象或者没有创建对象,因为如果常量池中有此字符串则不创建,否则就创建;
而String b=new String("java")  则一定会创建一个对象,不论常量池中是否已有此字符串。。
发表于 2021-03-13 11:06:34 回复(0)
这题目不严谨,也可以是另外一个答案,这条语句中,创建了4个对象。具体来说,"welcome"和"to"都是String对象,360是一个int类型的基本数据类型,将其转换成字符串时会创建一个新的String对象。此外,将这三个字符串连接起来时,也会创建一个新的String对象。因此,总共创建了4个对象。
发表于 2023-07-09 19:02:04 回复(1)
字符串想加,先拼接,后开辟空间。
发表于 2023-03-03 09:58:46 回复(0)
“x”+“a”这种字面量相加的在编译阶段就会优化成“xa”
发表于 2022-11-13 22:37:22 回复(0)
我觉得这个题目应该是存在一定歧义的。应该在题目前给出在字符串常量池中是否已经存在了“welcometo360”,如果有则题目答案创建了0个对象;如果没有的话,则在常量池中创建一个welcometo360”,并将地址值赋给s。
发表于 2022-01-09 20:53:55 回复(0)
是否大家有没有刷到这类面试题:在执行String s = "Hello";s = s + " world!";这两行代码后,原始的String对象中的内容到底变了没有? 答案的解析: 没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 "Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。 通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。 同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做: public class Demo { private String s; ... public Demo { s = "Initial Value"; } ... } 而非 s = new String("Initial Value"); 后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。 上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。 至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即 StringBuffer。 说说我的看法:字面量的创建是发生在编译期,类似于上述面试题,答案只创建一个对象。
发表于 2021-10-22 15:02:36 回复(0)
如果字符串常量池没有welcome和to会创建这两个对象,然后字符串拼接也会创建一个StringBuilder对象,StringBuilder使用toString转String时也会创建一个String对象,因此可以是1个或者4个
发表于 2021-09-15 09:54:09 回复(0)