2. 关于StringBuffer 创建对象和append函数传入null对象的情况

看下面的程序和输出结果:
代码:

		String str = null;
		StringBuffer sb = new StringBuffer();
		sb.append(str);
		
		System.out.println(sb);
		System.out.println(sb.length());
		
		StringBuffer sb1 = new StringBuffer(str);
		System.out.println(sb1);

输出结果:

null
4
Exception in thread "main" java.lang.NullPointerException
	at java.lang.StringBuffer.<init>(StringBuffer.java:139)
	at Test.main(Test.java:17)

这是为什么呢,我们来分析一下:

我们先来分析一下前两行的输出:

null
4

str对象是null,
但从输出来看sb并不是null,而是长度为4的字符串,这四个字符保存着正是字符串"null".
我们来可看一下append的底层代码:

    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    ================================================
        public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
    =====================================================
        private AbstractStringBuilder appendNull() {
        int c = count;
        ensureCapacityInternal(c + 4);
        final char[] value = this.value;
        value[c++] = 'n';
        value[c++] = 'u';
        value[c++] = 'l';
        value[c++] = 'l';
        count = c;
        return this;
    }

  1. StringBuffer append函数中的str仍然为null,然后传给AbstractStringBuilder append
  2. AbstractStringBuilder append 中判断str为null,然后调用AbstractStringBuilder appendNull
  3. AbstractStringBuilder appendNull 中把字符串"null"赋给保存数据的value,然后设置长度.所以输出的
    null
    4

我们再来分析那个异常

上面既然append,能把null对象保存为字符串"null",为什么当用null对象new 一个StringBuffer对象是会发生异常呢,我们还是来看底层代码:

    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

通过异常信息,发生异常就是代码"super(str.length() + 16);",
这里传进来的str是null,而str.length()相当于null.length(),因此发生了异常

发布了18 篇原创文章 · 获赞 1 · 访问量 200

猜你喜欢

转载自blog.csdn.net/andyonlines/article/details/103689105