什么时候使用StringBuilder或者Stringbuffer

什么时候使用Stringbuilder

  • 前言
    • 开篇三问
    • 综上
    • 结尾

前言

给3个建议:
1.没有在循环体中修改字符串的情况,不要轻易用StringBuilder,如果理解不深,容易适得其反;
2.在代码中写sql有时候很长,直接用“+”号拼接;
3.代码中sql的参数用问号代替,用预编译的形式,产生的垃圾对象是最少的。

如果要问为什么,请看下面;

开篇三问

1问下面代码产生了再会产生几个对象

private static String test1() {
		String str = "hello " + "word" + "!!";
		return str;
	}

答:在不考虑前后代码关系的情况下,这里只会产生1个对象!具体分析很简单,通过class文件反编译就能看到结果“”

  private static String test1() {
    String str = "hello word!!";
    return str;
  }

反编译之后,那些“+”号已经被java编译器处理了,这段代码运行过程大概是这样的:1.产生一个匿名字符串对象"hello word!!"直接入池;2.str指向常量池"hello word!!"地址。

2问不考虑前后影响,下面代码会产生几个对象,str指向的是不是常量池;

private static String test2() {
		String str1 = "word";
		String str = "hello "+ str1 + "!!";
		return str;
		
	}

答:产生了4个对象。str指向的不是常量池。看反编译结果:

 private static String test2() {
    String str1 = "word";
    String str = "hello " + str1 + "!!";
    return str;
  }

四个对象分别是池中的 “word”、"hello "、 "!!“和非池中的"hello word!!”;为啥"hello word!!"没有入池,因为String str = "hello " + str1 + “!!”;等效于 String str = new StringBuilder().append( "hello ").append( str1).append( “!!”) .toString()。这里面产生了两个字符串的匿名对象,和一个StringBuilder对象,感觉还好。

3问下面代码会产生几个对象

	private static String test3() {
		String str = "-1";
		for(int i =0;i<10;i++ ) {
			str += i;
		}
		return str;
	}

答:这个才是使用StringBuider或者buffer的场景。11个对象,最终没有入池。因为这段代码编译后将等效于下面这段代码,没进入一次循环体都会创建一个对象,

private static String test() {
		String str = "-1";
		for(int i =0;i<10;i++ ) {
			str =new StringBuffer().append(str).append(i).toString();
		}
		return str;
	}

综上

不是每个场景都要用StringBuilder的,要具体情况具体分析。除了循环修改字符串的情况,其他情况尽量不要手撸StringBuilder。有必要的时候java会帮忙优化的,这样还能保持较高的可读性。对于较长的sql拼接,有时候还会涉及StringBuilder扩容问题,让程序性能更差(当然明白这一点之后还是可以手动优化的);

如果一定要用,那可以先看看StringBuilder的构造方法,对于确定长度的字符串拼接,其中还有变量的,可以自己定义长度,避免扩容给效率带来影响。

结尾

上面的结论90%我都通过自己的方法验证过,部分结论是通过别人的资料的出来的。有兴趣提供验证方法的请留下评论。

你可能感兴趣的:(基础)