string中“+”号重载及intern方法

以下内容为thinking in java(p504-p509)总结:
java中没有运算符重载,但实际上“+”在java中实现了重载,一条语句中第一个”+“当且运算的一方为String对象时,是将另一方转化为字符串并将两个字符串拼接在一起,其实现是在编译时如果发现一条语句中第一个“+”一方为String对象,则创建一个stringbuilder对象,利用其append方法 ,最后toString转换为字符串返回。可以使用以下代码和javap命令验证。
javap是jdk自带的工具,实现反汇编,即将字节码文件转换为汇编语言。以下代码:

public class TestString{

    public  String concat() {

        String str = "";
         return str+"hello"+"world"+"java!"+this;

    }

    public static String concatenation (String str) {
        for (int i=0;i<6;i++) {
            str+=i+",";
        }
        return str;
    }
    public static String concatenation (StringBuilder sb) {
        for (int i=0;i<6;i++) {
            sb.append(i+",");
            //sb.append(",");
        }
        return sb.toString();
    }
    public static void main(String[] args) {

        String str = "";
        StringBuilder sb = new StringBuilder();
        concatenation(str);
        concatenation(sb);

    }
}

先将该java文件编译,再使用javap -c命令查看反编译代码,第一个方法反编译结果为:
public java.lang.String concat();
Code:
0: ldc #2; //String
2: astore_1
3: new #3; //class java/lang/StringBuilder
6: dup
7: invokespecial #4; //Method java/lang/StringBuilder.””:()V
10: aload_1
11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6; //String hello
16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: ldc #7; //String world
21: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: ldc #8; //String java!
26: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
29: aload_0
30: invokevirtual #9; //Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
33: invokevirtual #10; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
36: areturn
发现第3:创建stringBuilder对象, 第7:初始化, 第11:开始调用append方法,添加对象,最后调用自身toString方法并返回。
我们发现一条语句中“+”一方第一次出现字符串对象,则会创建stringBuilder对象,那么编译器自动创建并转换和手动编码并转换有什么区别呢?以两个循环方法为例:
public static java.lang.String concatenation(java.lang.String);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 6
5: if_icmpge 38
8: new #3; //class java/lang/StringBuilder
11: dup
12: invokespecial #4; //Method java/lang/StringBuilder.””:()V
15: aload_0
16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: iload_1
20: invokevirtual #11; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
23: ldc #12; //String ,
25: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: invokevirtual #10; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: astore_0
32: iinc 1, 1
35: goto 2
38: aload_0
39: areturn
第5:进入循环,每次循环创建一个StringBuilder对象,初始化后append添加,并自动toString,将堆内存首地址值赋给str,最后返回。
而手动编码并转换的过程如下:
public static java.lang.String concatenation(java.lang.StringBuilder);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 6
5: if_icmpge 27
8: aload_0
9: iload_1
10: invokevirtual #11; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
13: pop
14: aload_0
15: ldc #12; //String ,
17: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: pop
21: iinc 1, 1
24: goto 2
27: aload_0
28: invokevirtual #10; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
31: areturn
每次循环,直接调用stringBuilder对象append方法,最后显示调用toString并返回。相对于手动使用stringBuilder来说,前者占用内存空间且效率低。要注意的是,当在手动使用stringBuilder时如果使用”+“连接字符串则会创建新的stringBuilder对象。
然后,再讲一下String的intern方法,当String对象调用intern方法时,如果该对象与字符串常量池对象比较,存在相等的情况(根据equals方法返回值),则将常量池中该对象返回,否则,该对象加入到常量池中,并返回该对象的引用。intern方法的作用主要在于节约内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值