String拼接null字符遇到的问题


前言

昨天在做笔试题的时候遇到了一个之前没有遇见过的问题,所以特地记录下来。题目是这样的:

String s1 =  null;
String s2 = s1 + "hello";
System.out.println(s2);
//求上述s2的打印结果

我一开始认为既然s1是null,那不就说明s1什么都没有,那将它拼接到s2上去肯定结果还是"hello",于是想也没有想就直接选择了这个答案(PS:没看过String源码呀,所以完全不会o(╥﹏╥)o),最后在IDEA上进行验证果然给我好好上了一课。结果当然是nullhello。后来好奇在网上查找了有关技术文章才大致明白为什么会将null也作为一个字符串拼接上去。

提示:以下是本篇文章正文内容,下面案例可供参考

一、String的拼接操作: ‘’+‘’?

我们知道在String中有一个拼接操作,它的作用是将两个字符串进行拼接形成一个新的字符串。因为String是一个类,而"+“是String类中的一个操作。在Java中我们知道类中所有的"操作"都应该对应于一个方法。那么”+"对应哪个方法呢?不难发现当有变量参与字符串的拼接操作时,String会借用StringBuilder对象的append()方法来完成(JDK1.5之前借用StringBuffer)。
所以为了一探究竟,我们可以看一下append()方法的源码。

二、看源码

append()在JDK中的源码如下

代码如下(示例):

public StringBuilder append(String str) {
     super.append(str);
     return this;
}

这里我们发现它调用了父类的append()方法,那么它的父类又是哪个类呢?
通过查找发现有一个关系是StringBuffer、StringBuilder、String 对 CharSequence 接口的实现过程不一样,CharSequence 是一个定义字符串操作的接口,它只包括 length()、charAt(int index)、subSequence(int start, int end) 这几个 API。如下图所示:
在这里插入图片描述

在这里我们就不难发现String 是直接实现了 CharSequence 接口,而StringBuilder 和 StringBuffer 都是可变的字符序列,它们都继承于 AbstractStringBuilder,实现了 CharSequence 接口。所以显然super.append()调用的是父类AbstractStringBuilder中的append(),父类中append()的源码如下:

public AbstractStringBuilder append(String str) {
    if (str == null) {
        return appendNull();
    }
    int len = str.length();
    ensureCapacityInternal(count + len);
    putStringAt(count, str);
    count += len;
    return this;
}

从源码可知,当拼接null时,会调用appendNull()方法,其源码如下:

private AbstractStringBuilder appendNull() {
   ensureCapacityInternal(count + 4);
   int count = this.count;
   byte[] val = this.value;
   if (isLatin1()) {
       val[count++] = 'n';
       val[count++] = 'u';
       val[count++] = 'l';
       val[count++] = 'l';
   } else {
       count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
   }
   this.count = count;
   return this;
}

到这里我们就大致明白了当传入的字符串为null时,会调用appendNull()方法生成一个字符数组char[],并自动给这个字符数组拼接上’n’,‘u’,‘l’,'l’四个字符。所以最后s1的返回结果是字符串"null"。

总结

综上,本文重点是:String的"+"会调用StringBuilder的append()方法,然后顺着调用关系往下查阅源码即可知答案。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值