Java 重载方法的一些细节

今天开发过程中, 有遇到一个场景, 创建了 Http 工具类, 方法签名如下

  public void foo(String url, Object o) {
        System.out.println("foo(String str, Object o) 被调用...");
    }
    public void foo(String url, Map<String, Object> map) {
        System.out.println("foo(String str, Map<String, Object> map) 被调用...");
    }
    public void foo(String url, HashMap<String, Object> map) {
        System.out.println("foo(String str, HashMap<String, Object> map) 被调用...");
    }

于是好奇, 第二个参数传入 Map 对象, 那么真正哪个重载方法会被调用, 运行 test 方法

  /**
     * 重载方法形参涉及父子类时
     *      例如这里 Object > Map > HashMap
     *      重载方法会优先选择最具体的子类
     *      如果数据类型不匹配, 再向上查找
     *      都不满足, 则编译报错
     */
    @Test
    public void testOveride() {
        String str = "test";
        // 会选择 Object 方法
        foo(str, "你好鸭");

        Map<String, Object> map = new HashMap<>();
        map.put("key", 123);
        // 会选择 Map 方法
        foo(str, map);

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("key", 123);
        // 会选择 HashMap 方法
        foo(str, hashMap);
        
	 	Object obj = new HashMap<>();
        // 按照左侧参数声明类型调用, 而不是右侧的实现类类型
        // 会选择 Object 方法
        foo(str, obj);
    }

优先选择最具体形参的重载方法

查看字节码. 发现重载方法是在编译期确定的.

下图是最后一个方法的字节码, 可以看到调用的是 形参为 Object 的重载方法
字节码

由此验证后, 得到结论

重载方法是在编译期确定的

重载方法的形参涉及父子类时, 总是优先选择最具体形参的重载方法
并且需要注意的是, 是按照传入参数声明的类型去比较, 而不是 new 的类型.
即如果声明 Object map = new HashMap(); 那么会选择 Object 的重载方法, 而不是 HashMap 的那个重载方法

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值