现状:String.valueof() 处理null值时,会将null值转换为字符串null,从而赋值给属性。
代码示例
示例1:
@Test
public void test2(){
Map<String, Object> map = new HashMap<>();
map.put("name", null);
String str = String.valueOf(map.get("name"));
System.out.println(str);
}
结果:

示例2:
@Test
public void test1(){
String s = String.valueOf(null);
System.out.println(s);
}
结果2:
java.lang.NullPointerException
at java.base/java.lang.String.<init>(String.java:251)
at java.base/java.lang.String.valueOf(String.java:2965)
at cn.itcast.mq.helloworld.spring.SpringAmqpTest.test1(SpringTest.java:123)
问题:明明两个方法中传入的都是null值,为何一个报空指针异常,一个却是正常的。
分析过程:两者分别进入了不同的方法体中。
查看源码(示例1):
String str = String.valueOf(map.get("name"));
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
查看源码(示例2)
String str = String.valueOf(null);
public static String valueOf(char data[]) {
return new String(data);
}
public String(char value[]) {
this(value, 0, value.length, null);
}
原因:
- valueof方法被重载了多次,所以
String.valueOf(null)进入valurOf(char data[])方法,而该方法直接进入String构造器,内部会获取char[]的length,因此返回空指针异常。 String.valueOf(map.put("name"))进入了valuOf(Object obj)方法,参数为null时,返回一个字符串“null”。- 所以,出现不同结果。
问题:重载方法是如何被选择的?
- 多个重载方法均能匹配的条件下,优先会选择精度高的那个,也就是范围小的那个。即char[]和Object均能匹配null值,但char[]是继承自Object(数组也是一种特殊的Object),所以String.vauleOf(null)会优先选择精度高的char[]。而String.vauleOf(map.get(“name”))中map的value值已经声明为Object,所以它只能进入valueOf(Object obj)方法。
总结:java编译器在选择继承重载方法时,如果请求方法参数个数一致,且具备多个重载方法可以匹配到所传递的参数,此时,会优先选择精度相对较高的,即java继承树中树的深度较深的那个。
扩展(相关考题)
示例1:
public class TestNull {
public static void main(String[] args) {
test(null); //此处将返回arraylist,因为list同arraylist存在继承或实现的上下级关系
}
static void test(List list) {
System.out.println("list");
}
static void test(ArrayList list) {
System.out.println("arraylist");
}
}
结果:输出arraylist
示例2:
public class TestNull {
public static void main(String[] args) {
test(null); //本行会编译报错
}
static void test(String str) {
System.out.println("string");
}
static void test(Integer num) { //如果修改为int,则编译通过
System.out.println("integer");
}
}
结果:编译失败
原因:构造函数是编译时期确定的,代码将无法通过编译。因为String同Integer不存在任何关系,它们都继承自Object,公共父类是Object(String和String[]同理),此时null值不知道该传入哪一个方法,因此无法通过编译,直接报错。
博客围绕Java中null值处理展开,指出处理null值时会将其转为字符串null赋值给属性。通过代码示例分析了传入null值时,不同方法出现不同结果的原因,还探讨了重载方法的选择规则,即优先选精度高的,最后给出相关考题及编译报错原因。

2万+

被折叠的 条评论
为什么被折叠?



