append进StringBuilder里的字符串是""还是"null"? Java

有这样一个需求:有一个类,它有几个域,希望它的toString方法返回它的所有域的值组合成的字符串,域值之间用某种分隔符(比如####)分隔。我是这样实现的:

public class CombineFieldWithDelimiter {
    private String field1;
    private String field2;
    private String field3;

    public CombineFieldWithDelimiter() {
    }

    @Override
    public String toString() {
        String delimiter ="####";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(delimiter);
        stringBuilder.append(field1);
        stringBuilder.append(delimiter);
        stringBuilder.append(field2);
        stringBuilder.append(delimiter);
        stringBuilder.append(field3);
        return stringBuilder.toString();
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }

    public void setField2(String field2) {
        this.field2 = field2;
    }

    public void setField3(String field3) {
        this.field3 = field3;
    }

    public static void main(String[] args) {
        CombineFieldWithDelimiter combineFieldWithDelimiter = new CombineFieldWithDelimiter();
        System.out.println(combineFieldWithDelimiter.toString());
    }
}

当运行这个类的时候,我希望的输出是:

########

而实际上是:

null####null####null

为什么实际的输出和期望的不一样呢?看看StringBuilder的append(String)方法的源码:

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

继续查看它父类的append(String)方法的源码:

    public AbstractStringBuilder append(String str) {
        // null字符串当做"null"处理
        if (str == null) str = "null";
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

原来如此,当字符串为null时,就被当做”null”处理。因为我知道,如果没有显式的给CombineFieldWithDelimiter 类的各个域赋值,它们都将是null,所以,问题就明了了。为了解决问题,我只需显式的给每个域赋字符串”“就可以了,像下面这样:

public class CombineFieldWithDelimiter {
    private String field1 = "";
    ...
}

如果同学们对虚拟机中对象的创建过程不太了解,这里简单介绍一下。当我们new一个对象时,虚拟机首先去检查要创建对象的类是否已经加载(包括加载、连接和初始化)了,如果没有,就执行相应的类加载过程;然后虚拟机就给对象分配内存并把分配的内存空间都初始化为零值,给内存空间赋零值得操作使得对象的实例字段可以在不赋初始值的情况下也能直接使用,但都是相应的零值,对于对象域来说,就是null,理解了这一点,才算是真正理解本文了;最后是执行对象初始化方法<init>,给对象的域赋上程序员指定的值,例如,在我对上CombineFieldWithDelimiter的代买进行修改后,下面的语句执行后,

CombineFieldWithDelimiter combineFieldWithDelimiter = new CombineFieldWithDelimiter();

field1的值不是null,而是“”了。当执行完成后,一个真正可用的对象才算完全产生出来。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值