1.string.valueof("11"), "11"是字符串;String s =“” +11,11是整型; 2. string.valueof("11")调用的是: public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); } String s =“” +11,编译器会优化成,String s =new StringBuilder.append(“”) .append(11); 而.append(11)调用的是: public StringBuilder append(int i) { super.append(i); return this; } super.append(i); 调用的是: public AbstractStringBuilder append(int i) { if (i == Integer.MIN_VALUE) { append("-2147483648"); return this; } int appendedLength = (i < 0) ? stringSizeOfInt(-i) + 1 : stringSizeOfInt(i); int spaceNeeded = count + appendedLength; if (spaceNeeded > value.length) expandCapacity(spaceNeeded); Integer.getChars(i, spaceNeeded, value); count = spaceNeeded; return this; } 更加详细的自己看源代码。
关于字符串的+操作,单纯的String s ="" +11;编译器会看做常量""和常量11的拼接操作,常量计算最快; String.valueOf会调用方法,速度上会稍慢于常量+操作;另外,如果是这样: String str = ""; String s = str+11; 就不是常量+操作了,会通过SringBuilder(JDK1.6还是1.5版本开始用StringBuilder替换StringBuffer来实现字符串+)的append操作来拼接。耗时上看,常量+操作 最快,String.valueOf次之,字符串对象+操作最慢。可以通过javap -c 看看具体操作步骤,也可以通过测试代码直观比较耗时:public static void main(String[] args) { long t = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { String s0 = String.valueOf(11); } System.out.println("耗时" + (System.currentTimeMillis() - t)); t = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { String s = "" + 11; } System.out.println("耗时" + (System.currentTimeMillis() - t));
String str = ""; t = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { String s = str + 11; } System.out.println("耗时" + (System.currentTimeMillis() - t)); }
不知道楼上们用的什么编译器,我用的oracle的jdk1.7, 两者是有区别的 但是String s = "" + 11;和String s = "11"没区别,String s = "" + 11;中虽然写的是int类型的11,但"" + 11编译器会自动优化为"11"保存在常量池中 至于String.valueOf("11"), "11"也是作为字符串常量,保存在常量池中,但是调用了String.valueOf方法,该方法虽然只是一个很简单的判断, 不过效率应该是略低的
public class Test { public static void main(String[] args) { System.out.println(System.currentTimeMillis()); for(int i=0;i<10000;i++){ String s = new String(); s = 11+"aa"+0001+true; } System.out.println(System.currentTimeMillis()); for(int i=0;i<10000;i++){ StringBuilder sb = new StringBuilder(); sb.append(11).append("aa").append(0001).append(true); sb.toString(); } System.out.println(System.currentTimeMillis()); } }这样的运算时间明显不一样,而且第一个快
确实我的理解有误,忘记了 11+"aa"+0001+true; 都是常量,在编译时就优化成了s = "11aa0001true“;,如果改成 s +=11+"aa"+0001+true; 两个运行时间就应该一致了。
没区别,对String s = "" + 11,JVM帮我们调用了Stirng = "" + Integer.toString(11),
String.valueOf(int)方法其实也是调用了Integer.toString
2. string.valueof("11")调用的是:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
String s =“” +11,编译器会优化成,String s =new StringBuilder.append(“”) .append(11); 而.append(11)调用的是:
public StringBuilder append(int i) {
super.append(i);
return this;
}
super.append(i); 调用的是:
public AbstractStringBuilder append(int i) {
if (i == Integer.MIN_VALUE) {
append("-2147483648");
return this;
}
int appendedLength = (i < 0) ? stringSizeOfInt(-i) + 1
: stringSizeOfInt(i);
int spaceNeeded = count + appendedLength;
if (spaceNeeded > value.length)
expandCapacity(spaceNeeded);
Integer.getChars(i, spaceNeeded, value);
count = spaceNeeded;
return this;
}
更加详细的自己看源代码。
String.valueOf会调用方法,速度上会稍慢于常量+操作;另外,如果是这样:
String str = "";
String s = str+11;
就不是常量+操作了,会通过SringBuilder(JDK1.6还是1.5版本开始用StringBuilder替换StringBuffer来实现字符串+)的append操作来拼接。耗时上看,常量+操作 最快,String.valueOf次之,字符串对象+操作最慢。可以通过javap -c 看看具体操作步骤,也可以通过测试代码直观比较耗时:public static void main(String[] args) {
long t = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s0 = String.valueOf(11);
}
System.out.println("耗时" + (System.currentTimeMillis() - t)); t = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "" + 11;
}
System.out.println("耗时" + (System.currentTimeMillis() - t));
String str = "";
t = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = str + 11;
}
System.out.println("耗时" + (System.currentTimeMillis() - t));
}
但是String s = "" + 11;和String s = "11"没区别,String s = "" + 11;中虽然写的是int类型的11,但"" + 11编译器会自动优化为"11"保存在常量池中
至于String.valueOf("11"), "11"也是作为字符串常量,保存在常量池中,但是调用了String.valueOf方法,该方法虽然只是一个很简单的判断, 不过效率应该是略低的
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
for(int i=0;i<10000;i++){
String s = new String();
s = 11+"aa"+0001+true;
}
System.out.println(System.currentTimeMillis());
for(int i=0;i<10000;i++){
StringBuilder sb = new StringBuilder();
sb.append(11).append("aa").append(0001).append(true);
sb.toString();
}
System.out.println(System.currentTimeMillis());
}
}这样的运算时间明显不一样,而且第一个快
s +=11+"aa"+0001+true; 两个运行时间就应该一致了。
public class Test {
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
for(int i=0;i<10000;i++){
String s = new String();
s = 11+"aa"+0001+true;
}
System.out.println(System.currentTimeMillis());
for(int i=0;i<10000;i++){
StringBuilder sb = new StringBuilder();
sb.append(11).append("aa").append(0001).append(true);
sb.toString();
}
System.out.println(System.currentTimeMillis());
}
}反编译的字节码如下:
public static void main(java.lang.String[]);
Code:
0: getstatic #100; //Field java/lang/System.err:Ljava/io/PrintStream; 3: invokestatic #106; //Method java/lang/System.currentTimeMillis:()J
6: invokevirtual #110; //Method java/io/PrintStream.println:(J)V
9: iconst_0
10: istore_1
11: goto 28
14: new #115; //class java/lang/String
17: dup
18: invokespecial #117; //Method java/lang/String."<init>":()V
21: astore_2
22: ldc #118; //String 11aa1true
24: astore_2
25: iinc 1, 1
28: iload_1
29: sipush 10000
32: if_icmplt 14
35: getstatic #100; //Field java/lang/System.err:Ljava/io/PrintStream; 38: invokestatic #106; //Method java/lang/System.currentTimeMillis:()J
41: invokevirtual #110; //Method java/io/PrintStream.println:(J)V
44: iconst_0
45: istore_1
46: goto 85
49: new #60; //class java/lang/StringBuilder
52: dup
53: invokespecial #120; //Method java/lang/StringBuilder."<init>":()V
56: astore_2
57: aload_2
58: bipush 11
60: invokevirtual #121; //Method java/lang/StringBuilder.append:(I)Ljava/l
ang/StringBuilder;
63: ldc #124; //String aa
65: invokevirtual #71; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;
68: iconst_1
69: invokevirtual #121; //Method java/lang/StringBuilder.append:(I)Ljava/l
ang/StringBuilder;
72: iconst_1
73: invokevirtual #126; //Method java/lang/StringBuilder.append:(Z)Ljava/l
ang/StringBuilder;
76: pop
77: aload_2
78: invokevirtual #75; //Method java/lang/StringBuilder.toString:()Ljava/l
ang/String;
81: pop
82: iinc 1, 1
85: iload_1
86: sipush 10000
89: if_icmplt 49
92: getstatic #100; //Field java/lang/System.err:Ljava/io/PrintStream; 95: invokestatic #106; //Method java/lang/System.currentTimeMillis:()J
98: invokevirtual #110; //Method java/io/PrintStream.println:(J)V
101: return}可以看到
ldc #118; //String 11aa1true
在编译期就生成了String 11aa1true。
string 是=""+11;他新建了两个对象,速度慢,占用的内存也多些。