前几天看见了一道IBM的面试题
String s = "a" + "b" + "c" + "d" + "e";
问此语句共创建了几个对象,答案是
就创建了一个
String s = "a" + "b" + "c" + "d" + "e";
赋值符号右边的"a"、"b"、"c"、"d"、"e"都是常量
对于常量,编译时就直接存储它们的字面值而不是它们的引用
在编译时就直接讲它们连接的结果提取出来变成了"abcde"
该语句在class文件中就相当于String s = "abcde"
然后当JVM执行到这一句的时候, 就在String pool里找
如果没有这个字符串,就会产生一个
但是如果改成 String s = a+b+c+d+e;
呢 又是几个了。就是说上面是一个是因为 "a"、"b"、"c"、"d"、"e"都是常量
但如果是变量呢?
String s = "a" + "b" + "c" + "d" + "e";
问此语句共创建了几个对象,答案是
就创建了一个
String s = "a" + "b" + "c" + "d" + "e";
赋值符号右边的"a"、"b"、"c"、"d"、"e"都是常量
对于常量,编译时就直接存储它们的字面值而不是它们的引用
在编译时就直接讲它们连接的结果提取出来变成了"abcde"
该语句在class文件中就相当于String s = "abcde"
然后当JVM执行到这一句的时候, 就在String pool里找
如果没有这个字符串,就会产生一个
但是如果改成 String s = a+b+c+d+e;
呢 又是几个了。就是说上面是一个是因为 "a"、"b"、"c"、"d"、"e"都是常量
但如果是变量呢?
String s = a+b+c+d+e;
也是只有1个
首先s指向a 然后a+b 注意这里s 和s指向a 这两都没变
是a变成了ab
其他的同理
但是如果是这样的话就不一样了
String a = a;
String b = b;
String c = c;
String d = d;
String e = e;
String s = a+b+c+d+e;
答:IBM真是没完没了了.
String s = a+b+c+d+e;
这句话实际操作过程通过StringBuilder完成:
StringBuilder builder = new StringBuilder();
builder.append(a);
builder.append(b);
builder.append(c);
builder.append(d);
builder.append(e);
String s = builder.toString(); 去看StringBuilder的 toString()方法:
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
可以发现是通过new String(..)返回了一个在堆中建立的String对象,并且通过这种方法产生新String对象的过程与String str = new String("Hello");不同的是,常量池中并没有建立String常量对象。
所以说,不管有几个String变量相加,只有最后一步toString()才返回一个String对象,因此只创建了一个新的String对象,此对象在堆中。
因为对于楼主的解释
这个操作实际上是编译器完成的,因此可以认为是编译器实现的时候对于这种情况的优化,与JAVA语言本身的原理无关的。
有点糊涂,这里创建什么对象?
自己去看StringBuilder的代码,跟StringBuilder的父类中字符数组的大小有关,只有当数组容量不够的时候才会创建新数组,显然在这个问题中不会出现这个数组容量不够的问题.数组大小默认是16.
是变量,那么那些变量又分别指向什么呢?是指向同一个字符串还是不同的,没有给清楚啊
您只能输入 8000 个字符禁用UBB 内容存入剪贴板
一看就知道是经验派,IBM果然是大公司,这道题目是考验String栈内存和堆内存的机制,换句话说是考验你对程序运行效率的把握.
你文章中说:
我们先看看StringBuilder的构造器
public StringBuilder() {
super(16);
}看下去
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}可见,分配了一个16自己长度的char数组
.
但是我看到:toString()方法调用:new String(value, 0, count);方法,new String(value, 0, count)又调用Arrays.copyOfRange,copyOfRange中有char[] copy = new char[newLength];这不又是生成一个对象吗?