String.valueof(11);和String 是= ""+11;的区别

airy 2014-07-17 03:47:06
加精
如题,内部实现有什么区别,性能开销的区别
...全文
9825 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
采用string s = ""+11的方式会分为两步: 1.先建立“”对象 2.然后建立“”+11对象 也就是说要开辟两块内存 但是用第二种方式只需要开辟一块内存
cattpon 2015-10-08
  • 打赏
  • 举报
回复
应该是没区别才是~
luj_1768 2015-10-08
  • 打赏
  • 举报
回复
这个题看的人发蒙。 char a=11; 怎么理解?
qq_31150853 2015-10-01
  • 打赏
  • 举报
回复
写的不错。。。
cattpon 2015-09-28
  • 打赏
  • 举报
回复
引用 4 楼 gaofuqi 的回复:
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; } 更加详细的自己看源代码。
感谢正解分享~
阿飞不会飞丶 2015-09-25
  • 打赏
  • 举报
回复
确实应该学习这些细节
wust小吴 2015-09-24
  • 打赏
  • 举报
回复
问题出在 0+“” 这个不能乱用
peter_xizi 2015-08-03
  • 打赏
  • 举报
回复
引用 14 楼 fs08ab 的回复:
int n = Math.random(); String str1 = " + n; String str2 = String.valueOf(n); 这种写法,与题主的有区别吗,在效率和内存使用上哪个好,麻烦大神帮忙指导一下
对于“”+某个确定的值的操作,如String str1=""+1, ""+500这种操作,在编译期间会优化为常量,放在方法区的常量池中,使用常量效率肯定高, 而int n = Math.random()在编译期间是无法预知的,只有在运行期间才能得到具体的值,因此String str1 = ""+n也是需要在运行期间计算得到的,实现起来是利用StringBuilder完成字符串拼接的, 而String.valueOf(n),内部也会利用StringBuilder完成拼接,应该多了一个缓存的处理(ps:时间久了,忘记了具体实现过程,但是我清楚地记得Integer.valueOf是有缓存功能的,建议查看一下String类的源码)
lrq_ACMer 2015-08-01
  • 打赏
  • 举报
回复
这个不用在意吧,不在乎这一点开销 的区别
fs08ab 2015-07-28
  • 打赏
  • 举报
回复
int n = Math.random(); String str1 = " + n; String str2 = String.valueOf(n); 这种写法,与题主的有区别吗,在效率和内存使用上哪个好,麻烦大神帮忙指导一下
多木多多木 2015-07-28
  • 打赏
  • 举报
回复
楼主可以找一下关于String池部分的内容。
多木多多木 2015-07-28
  • 打赏
  • 举报
回复
引用 12 楼 rumlee 的回复:
效果一样,内部实现确实有区别,但是作为java程序员根本没有必要在乎这中区别,不如把更多的精力放在其他方面(例如数据库的设计优化、网络、多线程的优化等)。在乎这种内存的区别毫无意义,只能说是闲的蛋疼。 又不是做单片机编程,在乎这种。
哥,非常赞同,但有的时候面试题就这么钻牛角尖。
shine333 2014-07-18
  • 打赏
  • 举报
回复
全部是编译期常量的String加法操作,编译时候,自动编译成一个字符串——没有中间内容——运行时候直接常量 String.valueOf之类的方法调用,享受不到编译期优化
rumlee 2014-07-18
  • 打赏
  • 举报
回复
效果一样,内部实现确实有区别,但是作为java程序员根本没有必要在乎这中区别,不如把更多的精力放在其他方面(例如数据库的设计优化、网络、多线程的优化等)。在乎这种内存的区别毫无意义,只能说是闲的蛋疼。 又不是做单片机编程,在乎这种。
z8380019 2014-07-17
  • 打赏
  • 举报
回复
String.valueof(11).他是从常量池里面取数据,速度快。 string 是=""+11;他新建了两个对象,速度慢,占用的内存也多些。
gaofuqi 2014-07-17
  • 打赏
  • 举报
回复

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。
gaofuqi 2014-07-17
  • 打赏
  • 举报
回复
引用 7 楼 happy7023 的回复:
[quote=引用 4 楼 gaofuqi 的回复:] 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; } 更加详细的自己看源代码。
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());
	}
}
这样的运算时间明显不一样,而且第一个快[/quote]
引用 7 楼 happy7023 的回复:
[quote=引用 4 楼 gaofuqi 的回复:] 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; } 更加详细的自己看源代码。
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());
	}
}
这样的运算时间明显不一样,而且第一个快[/quote] 确实我的理解有误,忘记了 11+"aa"+0001+true; 都是常量,在编译时就优化成了s = "11aa0001true“;,如果改成 s +=11+"aa"+0001+true; 两个运行时间就应该一致了。
airy 2014-07-17
  • 打赏
  • 举报
回复
引用 4 楼 gaofuqi 的回复:
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; } 更加详细的自己看源代码。
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());
	}
}
这样的运算时间明显不一样,而且第一个快
secret32 2014-07-17
  • 打赏
  • 举报
回复
不知道楼上们用的什么编译器,我用的oracle的jdk1.7, 两者是有区别的 但是String s = "" + 11;和String s = "11"没区别,String s = "" + 11;中虽然写的是int类型的11,但"" + 11编译器会自动优化为"11"保存在常量池中 至于String.valueOf("11"), "11"也是作为字符串常量,保存在常量池中,但是调用了String.valueOf方法,该方法虽然只是一个很简单的判断, 不过效率应该是略低的
oh_Maxy 2014-07-17
  • 打赏
  • 举报
回复 1
关于字符串的+操作,单纯的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));
    }
加载更多回复(4)

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧