JavaSE StringBuffer的append()和构造器特别注意事项

    @Test
    public void testNull() {
        String str = null;
        StringBuffer sb = new StringBuffer();
        sb.append(str);//把str当成"null"这个字符串给放到sb里面去了

        System.out.println(sb.length());//4  sb因为放入了null这个字符串,所以长度变成了4

        System.out.println(sb);//null
        
        StringBuffer sb1=new StringBuffer(str);//抛异常,因为StringBuffer构造器会调用str.length(),但是str是个空的,就会抛异常
        System.out.println(sb1);//不执行
    }

上述代码多数人很容易搞错,尤其是在sout(sb.length());误认为输出的结果是0,但是结果是4

原因可以看源码知晓:

    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;
    }

StringBuffer是AbstractStringBuilder的子类,StringBuffer的append()方法继承于AbstractStringBuilder,而AbstractStringBuilder中有一个针对添加空指针的appendNull()

的方法,这个方法的源码强调当这个指针是空的时候,则设立一个长度为4的byte[](当中存储null这个字符串),所以当我们在输出StringBuffer对象添加空指针之后的长度,这个长度就变成了4,内容为null  ---> 这也就解释了为什么接下来的sout(sb)出的结果是null

第二个容易错的点就是:

StringBuffer sb1=new StringBuffer(str);

这个地方为什么会报错呢?还是需要看源码:

查看StringBuffer的构造器:

    @HotSpotIntrinsicCandidate
    public StringBuffer(String str) {
        super(str);
    }

发现这个构造器继承了AbstractStringBuilder的构造方法,我们点开super(str)看一看:

    AbstractStringBuilder(String str) {
        int length = str.length();
        int capacity = (length < Integer.MAX_VALUE - 16)
                ? length + 16 : Integer.MAX_VALUE;
        final byte initCoder = str.coder();
        coder = initCoder;
        value = (initCoder == LATIN1)
                ? new byte[capacity] : StringUTF16.newBytesFor(capacity);
        append(str);
    }

原因很明显:第一行str就可以看到,str调用了length(),直接会报NullPointerException空指针异常。

public NullPointerException() {
        super();
    }
原文地址:https://www.cnblogs.com/oldfish123/p/14507016.html