`
答案在风中
  • 浏览: 65552 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java札记(二)

阅读更多

       今天帮忙查bug发现了一个java中null值处理时候容易疏忽的问题,null值转换String类型时隐式的cast。

先看下null值在几个情景下的使用:

1.首先是控制台输出null值:

String str=null;
System.out.println(str);

上面这行代码的执行结果控制台输出结果是null,查看println函数发现其中使用了这样一个逻辑

if (s == null) {

   s = "null";

}

其实上面的语句在编译层面上与System.out.println((String)null)是等价的,只是通过对null值进行类型绑定避免了二义性(println(Object obj)/println(String str))。既然PrintStream重载了println(String str)、println(Object obj)我们也不难理解除去""和null本身含义的不一样的原因,统一使用字符串“null”作为对null的输出也保证了重载接口语义的一致性(null object返回空字符串很显然是不合理的)。

 

2.null值在+以及StringBuilder中的使用:

String str=""+null;

查看其对应的bytecode我们可以发现:

    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init>()V
    ACONST_NULL
    INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/Object;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

其实String str=""+null与String str=new StringBuilder("").append((Object)null).toString();从编译层面并没有太大区别(当然使用“+”编译器会进行一些优化,另外“+null”编译器编译时使用的是append(Object obj)从而避免二义性)。StringBuilder.append()中对与null值的处理方式也是使用字符串“null”而非空字符串。

 

废话了那么多,无非证明了一点,null和“”除了在某些String比较的情况下等价,大部分场景我们都应该谨慎地使用(String)null。例如+null以及append(null)再使用时也很容易犯错,下面就是今天遇到的案例。

import java.util.HashMap;
import java.util.Iterator;
public class TestHashMap {
	public static void main(String[] args){
		HashMap<String,String> hashMap=new HashMap<String,String>();
		hashMap.put("a", null);
		hashMap.put("b", "b");
		Iterator<String> iterator=hashMap.keySet().iterator();
		StringBuilder sb=new StringBuilder();
		while(iterator.hasNext())
		{
			String key=iterator.next();
			sb.append(key);
			sb.append(hashMap.get(key));
		}
		System.out.println(sb.toString());
	}
}

 返回的结果是b=ba=null,而不是我们期望的b=ba=,造成这个错误的原因根本上还是我们混淆了“”和null,想当然的认为append((String)null)的结果是空,总之要谨记null和”“是完全不相同的概念。

        此外一些key value类型的数据结构,在toString的时候对“”和null的处理也是不一样的,例如:

org.apache.http.message.BasicNameValuePair

public String toString() {
        // don't call complex default formatting for a simple toString
    	
    	if (this.value == null) {
            return name;
    	} else {
    		int len = this.name.length() + 1 + this.value.length();
            CharArrayBuffer buffer = new CharArrayBuffer(len);
            buffer.append(this.name);
            buffer.append("=");
            buffer.append(this.value);
            return buffer.toString();
        }
    } 

 

  欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

2
3
分享到:
评论

相关推荐

    JUnit使用札记

    总结来说,“JUnit使用札记”可能涵盖了如何创建和组织测试用例、如何利用JUnit注解来控制测试流程,以及如何结合实际的代码案例(如Sl330Case.java)来编写和运行测试。学习并熟练掌握JUnit对于任何Java开发者来说...

    JSP基础札记笔记

    ### JSP基础札记笔记 #### 第一讲:环境的配置 JSP(Java Server Pages)是一种基于Java技术的Web开发技术,用于创建动态网页。为了进行JSP开发,需要搭建相应的开发环境。 - **配置虚拟目录**:首先,需要创建一...

    学习PMD软件中的札记

    在"学习PMD软件中的札记"中,我们重点探讨了如何利用PMD来提升代码质量,并关注了`UseSingleton`规则。 `UseSingleton`是PMD中的一个规则,其目标是检测那些可以被设计为单例(Singleton)但当前并未如此实现的类。...

    Masm汇编札记Masm汇编札记Masm汇编札记

    相比于高级语言如C++或Java,汇编语言与硬件交互更为直接,能够提供更高的控制精度和执行效率。Masm作为一款功能强大的汇编器,不仅支持x86架构,还支持x64架构,使得开发者能够在不同平台上编写出高性能的应用程序...

    JVM学习札记

    ### JVM学习札记 #### 一、JVM运行机制 ##### 1、JVM的启动流程 JVM的启动过程主要包括以下步骤: 1. **加载配置文件**:JVM启动时,首先会根据当前路径寻找配置文件`JVM.CFG`,这个文件包含了JVM的一些基础设置...

    MINA使用札记(CumulativeProtocolDecoder使用)

    《MINA使用札记——CumulativeProtocolDecoder使用详解》 MINA(Java Multithreaded Network Application Framework)是一个强大的、高性能的Java网络应用框架,它主要用于构建可伸缩的、高性能的服务端应用,如...

    0-学习札记快速整理软件-小组成员及分工1

    常见的框架有Java的Spring Boot、Python的Django或Flask、前端的React或Vue.js等。团队成员需要根据项目需求和技术栈来决定最适合的框架,并负责编写实现基础功能的代码,确保软件能够正常运行。 代码优化是提升...

    401java-reading-notes

    描述中的“札记”表明这些笔记是以记录形式存在的,可能是课堂笔记、阅读摘录、实践经验和理解心得的集合。它们可能包含了讲师讲解的重点、示例代码、理论解释以及解决实际问题的方法。通过“来自代码研究员训练营的...

    背包客,旅游社交应用backpacker.zip

    前端技术: ...Java:一种广泛用于后端开发的编程语言,常用于构建企业级应用。 Python:一种多用途编程语言,在Web开发中常用。 Ruby on Rails:一个基于Ruby编程语言的Web应用框架,提供了高效的开发工具。

    reading-notes

    札记本网站为阅读笔记,总结所有阅读将在102、201和301中进行,它具有标题和摘要链接代码301-中间软件开发代码301阅读笔记页面链接描述 响应式和浮动式 jQuery的柔性 网格 赫鲁库 Node.js原料药Java脚本Java脚本Java...

    jsp&servlet_notebook

    【JSP&Servlet学习札记】是一份详细记录了JavaServer Pages(JSP)和Servlet核心技术的学习笔记。这些技术是Web开发中的重要组成部分,尤其在企业级应用开发中广泛使用。下面将对JSP和Servlet的主要概念、核心功能...

    Clojure Handbook(2012.11.1)

    这份手册的写作风格非常接近技术札记,不同于正式的书籍或手册。作者强调了笔记的实用性和个人特色,它更适合那些已经具备一定编程背景、特别是有Java经验的开发者,想要快速入门Clojure的人。 Clojure Handbook的...

    javaMail.zip

    JavaMail 是一个开源的Java库,它为Java程序员提供了处理电子邮件的能力。这个“javaMail.zip”文件包含了必要的jar包,使开发者能够在Java应用程序中实现发送邮件的功能。在JavaMail API的帮助下,开发人员可以轻松...

    readingnotes:代码201阅读笔记

    札记的形式使得内容更加聚焦于关键点和理解难点,帮助读者更好地消化和吸收编程知识。 在深入阅读和理解代码的过程中,有几个重要的知识点是不容忽视的: 1. **编程基础**:这是所有程序员的起点,包括基本语法、...

    simplenote:写日志的简约风格网站,欢迎使用和建议

    札记 技术要点: RPC: 登录及权限操作redis + session处理 搜索文章基于elasticsearch (内存不够了,暂停使用☻) 评论和关注等消息基于activemq: 数据结果处理: 开发: master采用的是rpc的微服务架构。 正常...

Global site tag (gtag.js) - Google Analytics