尼玛呀,到底创建了几个String对象啊?

今天在交流群里看到有一位仁兄问了一个java String对象方面的问题!

题目如下:

String s = "abcd";

s += "efgh";

s = s.substring(2,5); 

s = s.toUpperCase()

return s.toString();
请问以上代码在运行时会创建几个String对象呢? 答案:3个 (这样的问题 不乏很多童鞋在面试的时候会遇到,包括我在内! )。


这样的问题对我而言就想喝了二两一样,可能其他童鞋也有同感!下面我撸一下,哈哈:

String s = "abcd";  毫无疑问,这段代码创建了一个对象。

过程:当执行String s = "abcd"时,jvm首先会在String Pool中查找是否已经有了“abcd”这个字符串对象,如果存在这个对象,就会直接使用这个对象。反之,则会在String Pool中创建一个"abcd"字符串对象,然后讲引用s指向这个创建的对象。(如果 String s = new String("abcd"),又会是怎么样呢?呵呵!!!)。

s += "efgh"; 未创建对象。

过程:这个其实是jvm做了优化处理,通过反编译class文件可以看到如下代码:

s = (new StringBuilder(String.valueOf(s))).append("efgh").toString();

看到这个,我就不多说了,呵呵呵。

s = s.substring(2,5);创建了一个对象。

过程:我们看下jdk关于String中substring方法的定义吧!

 public String substring(int beginIndex, int endIndex) {
	if (beginIndex < 0) {
	    throw new StringIndexOutOfBoundsException(beginIndex);
	}
	if (endIndex > count) {
	    throw new StringIndexOutOfBoundsException(endIndex);
	}
	if (beginIndex > endIndex) {
	    throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
	}
	return ((beginIndex == 0) && (endIndex == count)) ? this :
	    new String(offset + beginIndex, endIndex - beginIndex, value);
    }
我们可以很清楚滴看出,如果截取的长度不是字符串本身的话,都会new String();


s = s.toUpperCase():  会创建一个对象。

过程: 参见jdk源码关于String中toUpperCase的定义。如果s字符串中有需要被转为大写的条件存在,必将创建一个新的String对象。如果没有满足的条件则返回this,也就是本身。(源码我就不贴了,太多了!)

s.toString(): 没有创建对象

过程:参见 jdk源码定义,可以看到返回的就是它本身。

 public String toString() {
	return this;
    }

好了,到此为止疑问全部解决完毕!希望对别人有点帮助,也可以扔砖砸我哦!!!



你可能感兴趣的:(java,String,String创建对象)