string连接符"+"

string连接符”+”

1.来来来,有个string的面试题想找你谈谈,废话不多说,上菜!!
public class Test{
    String a = "abc";
    String b = "a" + a;
}

这里创建了几个对象(常量池里面的对象也算)

最直观的办法还是看源码!这个怎么搞,不用怕,我们去分析编译过的class文件。这里需要用到javap命令

javac Test.java
javap -c Test

我们会得到如下内容

public static void main(java.lang.String[]);
    Code:
        //ldc(loadConstant) 将常量池中的"abc"放入栈顶
       0: ldc           #2                  // String abc
       //将常量池中"abc"的引用存到第一个局部变量a中
       2: astore_1
       //新建一个StringBuilder的对象
       3: new           #3                  // class java/lang/StringBuilder
       //复制栈顶的内容
       6: dup
       //调用StringBuilder构造器
       7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
       //将常量池中的"a"放入栈顶
      10: ldc           #5                  // String a
      //调用stringBuilder的append方法
      12: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      //装载第一个局部变量a的值
      15: aload_1
      //调用stringBuilder的append方法
      16: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      //将append的值变为string
      19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      //将生成的string的引用存到第二个局部变量b中
      22: astore_2
      23: return
}

可以看到创建的对象:

在常量池中存在 “abc” 和”a” 两个对象

在堆中创建了StringBuilder对象 ,最后调用toString方法产生一个String对象,里面存”aabc”

答案出来了。这里产生了4个对象。

2.现在再来看两句熟悉的代码
String a = "a";
System.out.println(1+2+a); //Q1
System.out.println(a+1+2); //Q2

分析:

​ Q1的输出? “12a” 还是 “3a”

​ Q2的输出? “a12” 还是”a3”

​ 其实这个题目对比起来看很容易明白,机智的你应该已经发现了端倪。编译器会优先做 “+”运算,当”+”连接的是整形时,先做加法运算,如果连接的是字符串,那么便是字符连接了。所以Q1的结果是”3a”,Q2是”a12”

3.第三个问题来了
String a = null ;
Integer b = null;
System.out.println(a); //Q1 "null"
System.out.println(a + 2); //Q2 "null2"
System.out.println(b + 2);//Q3 异常

分析:

​Q1是个选择题,选项有空字符串、null、抛异常,当时我就懵逼了。后来去看了源码,Q1代码会直接去找

public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
}
然后
public void print(String s) {
        if (s == null) {
            s = "null";
        }
        write(s);
}

好的,找到答案了!是”null”
​那么Q2呢,Q2执行也会去找println(String x)这个方法,但是此时x已经是”null2”了,所以下面的if判断不会执行的,那么什么时候x变成了”null2”呢?
此时继续查看,会找到一个String.valueOf(Object)的静态方法。到这里大boss出来了,打断点你会发现,不管你执行什么代码,都会走这个方法,这里是是一个反射的源头,是通过这个,最后确定对象的类型,以及返回值。所以”a+2”先确认了返回字符串,然后再去拼接,看class文件你会看到括号里面的内容是(“”+object+2) 。
所以结果出来了,同理Q3也是先确认了返回的括号里面的类型是int,然后做加法运算,括号里面的内容是(((Integer)b).intValue() + 2),但是b对象是空,,所以抛出了null指针异常

另附上一些能帮助理解String的面试题

http://blog.csdn.net/chj97/article/details/6899598

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值