String.valueof() 处理null值问题【会将null转为字符串】

博客围绕Java中null值处理展开,指出处理null值时会将其转为字符串null赋值给属性。通过代码示例分析了传入null值时,不同方法出现不同结果的原因,还探讨了重载方法的选择规则,即优先选精度高的,最后给出相关考题及编译报错原因。
该文章已生成可运行项目,

现状: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值不知道该传入哪一个方法,因此无法通过编译,直接报错。

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值