首页 > 试题广场 >

Java语言中,String s =new String(“

[单选题]
Java语言中,如果"xyz"没有被创建过,String s =new String(“xyz”);创建了几个string object?
  • 1
  • 2
  • 3
  • 4
两个。第一个在堆中,第二个在字符串常量池中!如果在Java字符串常量池中已经存在,就只会创建一个
编辑于 2017-09-27 11:21:54 回复(14)

相关知识点

类加载对一个类只会进行一次。
"xyz" 在类加载时就已经创建并驻留了(如果该类被加载之前已经有 "xyz" 字符串被驻留过则不需要重复创建用于驻留的"xyz"实例)。

驻留的字符串是放在全局共享的字符串常量池中的。

在 HotSpot VM 里实现的 string pool 功能的是一个 StringTable 类,它是一个哈希表,里面存的是驻留字符串(也就是我们常说的用双引号括起来的)的引用(而不是驻留字符串实例本身)
也就是说在堆中的某些字符串实例被这个 StringTable 引用之后就等同被赋予了”驻留字符串”的身份。
这个 StringTable 在每个 HotSpot VM 的实例只有一份,被所有的类共享。


在这段代码后续被运行的时候,"xyz" 字面量对应的 String 实例已经固定了(前面的类加载过程),不会再被重复创建。

所以这段代码将常量池中的对象复制一份放到 heap 中,并且把 heap 中的这个对象的引用交给 s1 持有。

简单理解

对于这句代码,可分为两个过程:

  1. jvm 首先在字符串常量池内里面看看找不找到字符串"xyz";找到,进入第二步;否则,创建新的 String 对象,并“放到”字符串常量池里面。
  2. 然后由于遇到了 new,还会在堆创建 String 对象,其实实际是引用的常量池的那个,最后将其返回给 s1。

将new String("xyz")拆分为new String()和"xyz"
如果写在类方法里,请参考前面的类加载,就是相比之下提前驻留了吧。

编辑于 2019-03-25 13:19:26 回复(5)
这题出的有歧义,可能有一个,也有可能是两个,“xyz”对应一个对象,这个对象存放在字符 串常量缓冲区,不管常量“xyz”出现多少遍,都是缓冲区的那一个,new String每写一遍就创建一个新的对象,如果之前用过“xyz”,那就不会创建,直接从缓冲区拿。所以说可能一个或者两个对象
发表于 2017-04-27 18:03:23 回复(10)
两个。原因如下:
String类新建对象的时候,会首先在字符串常量池中检查该对象是否存在,如果不存在则新建。所以字符串常量池中没有相同的字符串存在
常量池创建对象完成(如果不存在),则在堆中再创建对象。如下图:

发表于 2019-04-01 18:10:40 回复(0)
而String str = new String("xyz");会进行两步操作: 1、先在堆中创建一个指定的对象"xyz",并让str引用指向该对象。 2、在常量池中 寻找或新建 一个”xyz”,并让堆中对象与之关联。
发表于 2018-04-16 17:25:35 回复(0)
很明显啊,xyz上面有双引号,也就是说是一个字符串变量,字符串常量池中创建的,而new操作符,不是在堆中开辟内存吗,s指向这块堆内存的首地址。这不就两次嘛?对吗,各位大佬们?
发表于 2017-08-26 11:07:28 回复(0)
拓展一下吧,如果问的是几个地方分配了内存,应该是3个,s存在栈中,然后堆中有一个,字符常量池有一个
发表于 2019-03-23 17:10:52 回复(1)
明显是创建1个对象,不信你们自己去javap 一下,“xyz”是会当做字面量常量,直接进入常量池,根本不会new
发表于 2017-08-25 22:14:56 回复(1)
s是栈中创建的String类型的引用变量,引用了堆中创建的new String变量地址。
所以应该是两个。
发表于 2017-04-22 14:00:36 回复(6)
从不同角度想,好多题都是模棱两可的,放在客观题里有点坑。
发表于 2017-08-25 23:34:35 回复(0)
没懂大家在说什么,一直以为是1个。大佬教教我
发表于 2018-03-27 16:14:40 回复(0)
这个题多捞啊
发表于 2018-02-01 16:13:37 回复(0)
很纳闷到底什么叫做 string object
发表于 2017-12-12 16:53:31 回复(1)
会创建两个对象
题干要求未创建“xyz”字符串 证明字符串常量池中并没有该对象,因此需要在字符串常量池中创建一个副本,每当有对象指向该字符串时,将地址赋给该对象,并且这些对象可以使用==判断 返回值为true

其次String s,该语句会在堆中创建一对象,且该对象的地址指向字符串常量池中的“xyz”字符串
发表于 2019-09-03 13:23:15 回复(0)
 String a = new String("abc");
        String b = "abc";
        System.out.println(a == b);//false

看结果就可以看出new 出来String对象 并不是常量池中对象(直接进行" "赋值的就是常量池中的对象)
在使用 new String("")时会在堆内存中创建一个String对象,如果在常量池没有将会在常量池创建一个一模一样的String对象.那?在常量池中有的时候会在堆内存中创建对象吗?于是我做了个实验.
String a = new String("abc");
        String b = "abc";
        String c = new String("abc");
        System.out.println(c == a);//false
        System.out.println(c == b);//false
        System.out.println(a == b);//false

然而在结果是即便是常量池中存在,new 创建String对象也是一个新的对象
发表于 2019-08-22 11:14:29 回复(0)
字符串xyz会首先创建一个匿名对象,然后new String又创建了一个内容也为xyz的对象,之前创建的匿名对象xyz则会变为垃圾。所以一般创建字符串时采用直接复制的方法。
发表于 2019-08-07 10:38:00 回复(0)
string 的对象,并不包含引用
发表于 2019-05-29 22:00:59 回复(0)
堆中对象,常量池用常量
发表于 2019-04-20 14:50:56 回复(0)
在Java中,出现""就会去字符串常量池中创建一个字符串对象,而前面又使用new来创建对象会去堆中创建一个字符串对象,所以一共是2个
编辑于 2019-04-04 11:16:37 回复(0)