首页 分享 字符串String的+和+=及循环操作String的原理

字符串String的+和+=及循环操作String的原理

来源:花匠小妙招 时间:2024-11-08 00:49

String对象是不可变的:意思就是无论是对String的新增或修改,出现一个全新的String内容时,都意味着诞生了一个新的对象。但是如果内容不变的话,增加的只是对象的引用而已。

例如:

String a = "ljh"; String b = "ljh"; String c = "ljh"; System.out.println(a==b); System.out.println(b==c);

结果都是true

但是这种不可变性会产生一些性能上的问题,所以JVM对String对象重载“+”“+=”进行了一些优化

操作符“+”可以用来连接String

String aaa = "ljh"; String bbb = "big"; String ccc = aaa+bbb+"aaaa";

在jdk8中,上述代码中在底层其实是编译器擅自调用了StringBuilder类进行+的操作,主要原因是StringBuilder的append()更加高效,我们来看一下字节码。

public static void main(java.lang.String[]);

    Code:

0: ldc           #2                 

2: astore_1

3: ldc           #3                 

5: astore_2

6: new           #4                 

9: dup

10: invokespecial #5                 

13: aload_1

14: invokevirtual #6                 

17: aload_2

18: invokevirtual #6                 

21: ldc           #7                 

23: invokevirtual #6                 

26: invokevirtual #8                 

29: astore_3

30: return

可以看出一共有四个对象,分别是三个String 和一个StringBuilder

我们再来看一下+=

String a = "aaa"; a += "bbb";

字节码如下

Code:

0: ldc #2

2: astore_1

3: new #3

6: dup

7: invokespecial #4

10: aload_1

11: invokevirtual #5

14: ldc #6

16: invokevirtual #5

19: invokevirtual #7

22: astore_1

23: return

可以看出先创建了一个“aaa”字符串,然后当a遇到+=时,创建了一个StringBuilder对象,并append了aaa字符串。之后创建了一个“bbb”对象,然后append了bbb字符串,最后调用StringBuilder的toString方法。

接下来再看看循环中调用+=会是什么样子

String a = "aaa"; a += "bbb"; for(int i=0;i<5;i++){ a+="ccc"; }

Code:

0: ldc #2

2: astore_1

3: new #3

6: dup

7: invokespecial #4

10: aload_1

11: invokevirtual #5

14: ldc #6

16: invokevirtual #5

19: invokevirtual #7

22: astore_1

23: iconst_0

24: istore_2

25: iload_2

26: iconst_5

27: if_icmpge 56

30: new #3

33: dup

34: invokespecial #4

37: aload_1

38: invokevirtual #5

41: ldc #8

43: invokevirtual #5

46: invokevirtual #7

49: astore_1

50: iinc 2, 1

53: goto 25

56: return

可以看出先创建String对象aaa,之后创建StringBuilder并初始化StringBuilder append aaa,然后创建bbb对象,并append(  bbb),然后我们发现在循环中依旧创建了一个新的StringBuilder,也就是没经过一次循环都要创建一个新的StringBuilder对象。

这时我们做一个优化,提前创建StringBuilder对象

String a = "aaa"; a += "bbb"; StringBuilder sb = new StringBuilder(a); for(int i=0;i<5;i++){ sb.append("ccc"); }

Code:

0: ldc #2

2: astore_1

3: new #3

6: dup

7: invokespecial #4

10: aload_1

11: invokevirtual #5

14: ldc #6

16: invokevirtual #5

19: invokevirtual #7

22: astore_1

23: new #3

26: dup

27: aload_1

28: invokespecial #8

31: astore_2

32: iconst_0

33: istore_3

34: iload_3

35: iconst_5

36: if_icmpge 52

39: aload_2

40: ldc #9

42: invokevirtual #5

45: pop

46: iinc 3, 1

49: goto 34

52: return

可以看出循环体跳回34行,并不会不断地创建新的StringBuilder,大大提高了效率和减小了垃圾数量!,所以我们要注意自己的写法!避免无谓的消耗

相关知识

性能调优: df中的string wordcount
字符串
c++ TCHAR转string导致中文缺失或乱码问题及解决
字符串 (C++/CX)
字符串(C# 编程指南)
字符串基础(C# 编程指南)
input string was not in a correct
String对象的length属性的作用?
一文了解Simhash原理和用法
月月查华华手机(字符串操作)

网址: 字符串String的+和+=及循环操作String的原理 https://www.huajiangbk.com/newsview409475.html

所属分类:花卉
上一篇: 养久了才发现,被无数人吹捧的″蓝
下一篇: 梦幻少女心 常州达人打造现实版'

推荐分享