String中的“+”操作是怎么回事?

案例1:
String a = "ab";
String bb = "b";
String b = "a"+bb;
System.out.println(a==b);

这里输出的结果是false,为什么?

“String+变量”因为编译时无法进行优化,所以这一条语句的操作是在运行时进行的,且会产生新的对象,而不是直接从 jvm 的 string常量池中获取。

java 中 String 的“+”运算符编译后其实是转换成了这样的代码:

String b = new StringBuilder().append("a").append(bb).toString();

其中StringBuilder类重写的toString方法使用 new String(…)来构造一个 String 对象。JDK中的源代码如下:

@Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

通过new操作符创建的字符串对象不指向字符串池中的任何对象,但是可以通过使用字符串的intern()方法来指向其中的某一个。

我们来看一道经典面试题:
String str = new String(“abc”) 创建多少个对象?

这段代码执行过程如下:
1、在常量池中查找是否有“abc”对象。

     1.有则返回对应的引用实例;
     2.没有则创建对应的对象实例。   

2、在堆中 new 一个 String(“abc”) 对象。
3、将对象地址赋值给str,创建一个引用。
所以,常量池中没有“abc”字面量则创建两个对象,否则创建一个对象,以及创建一个引用。

根据字面量,往往会提出这样的变式题:
String str1 = new String(“A”+“B”) ; 会创建多少个对象?
String str2 = new String(“ABC”) + “ABC” ; 会创建多少个对象?

str1:
字符串常量池:“A”,“B”,“AB” : 3个
堆:new String(“AB”) :1个
引用: str1 :1个
总共 : 5个

str2 :
字符串常量池:“ABC” : 1个
堆:new String(“ABC”) :1个
引用: str2 :1个
总共 : 3个

案例2:

一个特殊的例子:

//“+”连接的都是字符串常量
String str = “This is only a” + “ simple” + “ test”;
StringBuffer builder = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

我们一般认为速度 StringBuilder>StringBuffer>String,但在此案例中
你会很惊讶的发现,生成 str 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,实际上:

String str = “This is only a” + “ simple” + “test”;

其实就是:

String str = “This is only a simple test”;

所以不需要太多的时间。但大家这里要注意的是,如果你的字符串是来自另外的String 对象的话,速度就没那么快了,譬如:

String str2 = “This is only a”;
String str3 = “ simple”;
String str4 = “ test”;
String str1 = str2 +str3 + str4; //“+”连接的是字符串变量

这时候 JVM 会规规矩矩的按照原来的方式去做。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值