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

本文深入探讨了Java中StringBuffer对象处理null值时的行为,解析了为何append方法可以将null转换为字符串null,而使用null初始化StringBuffer会抛出NullPointerException异常。通过分析源码揭示了背后的机制。

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

		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(),因此发生了异常

public static String actionPostStringToSCADA(HttpBaseEntity httpBaseEntity, String requestStr) { String responseStr = null; if (httpBaseEntity != null) { String domain = httpBaseEntity.getDomain(); String port = httpBaseEntity.getPort(); String resourcePath = httpBaseEntity.getResourcePath(); // //拼接出对应的地址 // String url = new StringBuffer("http://") // .append(domain) // .append(":") // .append(port) // .append("/") // .append(resourcePath) // .toString(); //拼接出对应的地址 String url = new StringBuffer("http://") .append(domain) .append(":") .append(port) .append("/") .append(resourcePath) .toString(); //输出url请求报文 System.out.println("actionPostStringToSCADA url:\n" + url); String requestJsonStr = requestStr; System.out.println("actionPostStringToSCADA requestJsonStr:\n" + requestJsonStr); //创建请求头,做规范 Map<String, String> headers = new HashMap<>(); // headers.put("Content-type", "text/xml;charset=UTF-8"); headers.put("Content-Encoding", "UTF-8"); headers.put("CharacterEncoding", "UTF-8"); //http post方式请求封装,数据传输格式默认为xml,获取相应的返回数据 responseStr = HttpUtils.HttpPostString( url, headers, requestJsonStr ); } return responseStr; } public static String HttpPostString(String url, Map<String, String> headers, String requestStr) { String responseStr = ""; HttpClient httpClient = null; HttpPost httpPost = null; try { if (org.springframework.util.StringUtils.hasLength(url) && url.startsWith("http://")) { httpClient = HttpClients.custom().build(); httpPost = new HttpPost(url); //组装http header httpPost.setHeader("Content-type", "text/xml;charset=UTF-8"); if (headers != null && headers.size() > 0) { for (Map.Entry<String, String> entry : headers.entrySet()) { httpPost.setHeader(entry.getKey(), entry.getValue()); } } //组装http entity if (org.springframework.util.StringUtils.hasLength(String.valueOf(requestStr))) { StringEntity entity = new StringEntity(String.valueOf(requestStr), Charset.forName("UTF-8")); entity.setContentEncoding("UTF-8"); entity.setContentType("text/xml"); if (headers != null && headers.size() > 0) { if (headers.containsKey("Content-Encoding")) { entity.setContentEncoding(headers.get("Content-Encoding")); } if (headers.containsKey("Content-Type")) { entity.setContentType(headers.get("Content-Type")); } } httpPost.setEntity(entity); } HttpResponse response = httpClient.execute(httpPost); int statusCode = response.getStatusLine().getStatusCode(); HttpEntity responseEntity = response.getEntity(); responseStr = EntityUtils.toString(responseEntity); System.out.println(statusCode + " | " + responseStr); } } catch (IOException e) { e.printStackTrace(); System.out.println("error:" + e.getMessage()); } finally { if (httpPost != null) httpPost.releaseConnection(); } return responseStr; }这是原先发送http逻辑,现在要改为json发送 应该如何修改
11-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值