String s=new String("abc") 创建了几个对象?

时间:2021-09-29 16:15:30

答案是2个,大家肯定都知道。面试中经常出现的问题,今天认真分析一下。

1、 Sting s    定义了一个变量s,没有创建对象;

2、 =    赋值,将某个对象的引用(句柄)赋给s ,没有创建对象;

3、 “abc”    创建一个对象;

4、 new String() 创建一个对象。


首先,总结一下java创建对象的方式:new、clone、反射、反序列化

看一下 Stirng的构造函数

public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}

所以,我们用了new 创建了一个对象,而“abc”是当做一个对象传过来的,so 就是两个了

进一步探究:
1、String s =  "abc"    
创建了一个对象;
2、 那么  String a="abc"   ;  String b="abc"  创建了几个对象呢??
答案还是一个;
3、那么 String s = "ab"+"cd";  呢???
答案是三个。

解释:

在jvm中有一个字符串池,保存了很多String对象,可以共享。所以String a="abc"   ;  String b="abc"  只创建了一个对象。而"ab"+"cd" 除了"ab"、"cd"还生产了新对象"abcd"。



下面有详细介绍,抄录自http://www.cnblogs.com/ydpvictor/archive/2012/09/09/2677260.html,特此声明。


在JAVA虚拟机(JVM)中存在着一个字符串池,其中保存着很多String对象,并且可以被共享使用,因此它提高了效率。由于String类是final的,它的值一经创建就不可改变,因此我们不用担心String对象共享而带来程序的混乱。字符串池由String类维护,我们可以调用intern()方法来访问字符串池。  

我们再回头看看String a="abc";,这行代码被执行的时候,JAVA虚拟机首先在字符串池中查找是否已经存在了值为"abc"的这么一个对象,它的判断依据是String类equals(Object obj)方法的返回值。如果有,则不再创建新的对象,直接返回已存在对象的引用;如果没有,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。因此,我们不难理解前面三个例子中头两个例子为什么是这个答案了。

只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入字符串池中。对于所有包含new方式新建对象(包括null)的“+”连接表达式,它所产生的新对象都不会被加入字符串池中,对此我们不再赘述。因此我们提倡大家用引号包含文本的方式来创建String对象以提高效率,实际上这也是我们在编程中常采用的。

栈(stack):主要保存基本类型(或者叫内置类型)(char、byte、short、int、long、float、double、boolean)和对象的引用,数据可以共享,速度仅次于寄存器(register),快于堆。 

堆(heap):用于存储对象