• 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();
        }
  • 相关阅读:
    "字符反向拼接"组件:<reverse> —— 快应用组件库H-UI
    "首字母变大写"组件:<capitalize> —— 快应用组件库H-UI
    "字母全变大写"组件:<uppercase> —— 快应用组件库H-UI
    "字母全变小写"组件:<lowercase> —— 快应用组件库H-UI
    "多行文本"组件:<multi> —— 快应用组件库H-UI
    "斜体显示"组件:<i> —— 快应用组件库H-UI
    捕捉AVPlayerViewController 系统原生工具栏的出现、隐藏事件
    (简单实用)Android支付宝商家收款语音播报
    使用wkwebview时,push后,再pop返回,报错
    安卓进度条两边圆角+渐变的拓展
  • 原文地址:https://www.cnblogs.com/oldfish123/p/14507016.html
Copyright © 2020-2023  润新知