我在搜索时,看到访问量上万的文章给出的解释竟然错误的。为了排除一些误导,特意为大家分析一下原因。
错误的原因分析
=======
如果对上述问题进行搜索,你可能看到的答案是:
s + " world" 等价于 s = String.valueOf(s)+“word”;
然后附带valueOf方法:
public static String valueOf(Object obj) {
return (obj == null) ? “null” : obj.toString();
}
你信了吗?如果信了可能真的就错了。下面我们就来分析分析为什么错了。
Java编译器的优化
==========
我们知道,当我们写下面的代码时Java编译器会为我们做一些优化:
String a = "Hello ";
String b = “World”;
System.out.println(a + b);
如何优化的?上面这段代码经过编译器优化之后,等价于:
StringBuilder sb = new StringBuilder();
sb.append("Hello ");
sb.append(“World”);
String result = sb.toString();
System.out.println(result);
也就是说,加号操作会被优化基于StringBuilder的操作,而并不是上面提到的String.valueOf操作。
那么,上面为null的情况也就等价于下面的操作了:
StringBuilder sb = new StringBuilder(null);
sb.append(“hello”);
sb.append(" world");
String result = sb.toString();
System.out.println(result);
此时,我们再看一下StringBuilder(null)这个构造方法的底层实现,最终调到它的父类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;
}
对应的appendNull方法实现为:
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;
}
在appendNull方法中就是将null当做字符串“null”来处理了。这也就是为什么会在拼接中出现null的原因。
字节码追踪
=====
针对上述示例,如果你想看编译器是如何处理的,可以通过javap -c 命令来查看对应字节码:
通过字节码可以看出,基本上与上面的分析的一致。所以说,尽信书不如无书。
拓展问题
====
解决了上述问题,再来看看,如果我们单纯地就打印null是怎么输出的?
总结
蚂蚁面试比较重视基础,所以Java那些基本功一定要扎实。蚂蚁的工作环境还是挺赞的,因为我面的是稳定性保障部门,还有许多单独的小组,什么三年1班,很有青春的感觉。面试官基本水平都比较高,基本都P7以上,除了基础还问了不少架构设计方面的问题,收获还是挺大的。
经历这次面试我还通过一些渠道发现了需要大厂真实面试主要有:蚂蚁金服、拼多多、阿里云、百度、唯品会、携程、丰巢科技、乐信、软通动力、OPPO、银盛支付、中国平安等初,中级,高级Java面试题集合,附带超详细答案,希望能帮助到大家。
的感觉。面试官基本水平都比较高,基本都P7以上,除了基础还问了不少架构设计方面的问题,收获还是挺大的。
经历这次面试我还通过一些渠道发现了需要大厂真实面试主要有:蚂蚁金服、拼多多、阿里云、百度、唯品会、携程、丰巢科技、乐信、软通动力、OPPO、银盛支付、中国平安等初,中级,高级Java面试题集合,附带超详细答案,希望能帮助到大家。
[外链图片转存中…(img-WG52ENh6-1714057497544)]