定义
在java中 null既不是对象,也不是一种类型,而是一种特殊的值。在这里我要说的是一种特殊情况哈。
编译器自带的优化
总所周知,我们的java代码中String对象那如果直接用+连连接字符串可能导致效率变低。但是现在在java1.5以后编译器对其自动做了优化,如果你有时间打开反编译的源码看看,你会发现,String a="b"+"cc";这个代码在编译器中优化了,优化方式为在这行代码的开始的地方声明一个StringBuilder,然后不断append后面的字符串。因此对于java来说你用StringBuilder和String的+其实效率都是一样的,但是为了保证一个良好的习惯还是用StringBuilder好一点。
+导致的问题
我们用""+null,这个空对象,会生成一个null字符串。这是为什么呢?
前文已经提到,我们已经用编译器做了优化,String对象的+被优化为了StringBuilder的append,然而我们看看append的源码,你就会发现为何是null字符串了。
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
查看源码发现,append方法向上调用了其抽象类AbstractStringBuilder方法的append方法,在看
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;
}
你看真相大白了,在这个抽象类的这个append方法中,先进行了判断,如果为null,则是把这个null作为一个字符串加上去。因此解决了上面我们遇到的问题,为何String对象+null,会条件一个null字符串。
测试案例如下:
public static void main(String[] args) {
String a="dh";
String b=a+null;
System.out.println(b);
}
结果如下:
dhnull