首页 > 解决方案 > 为什么我的原始类型参数方法不覆盖包装器类型参数超类方法?

问题描述

public class WrapperClasses{
    void overloadedMethod(Number N){
        System.out.println("Number Class Type");
    }

    void overloadedMethod(Double D){
        System.out.println("Double Wrapper Class Type");
    }

    void overloadedMethod(Long L){
        System.out.println("Long Wrapper Class Type");
    }

    public static void main(String[] args){
        int i = 21;
        WrapperClasses wr = new WrapperClasses();

        //wr.overloadedMethod(i);
    }
}

class mine extends WrapperClasses{
    void overloadedMethod(int N){
        System.out.println("Integer Class Type");
    }
    public static void main(String[] args){
        int i = 21;
        WrapperClasses wr = new mine();

        wr.overloadedMethod(i);
    }
}

这打印Number Class Type

我了解包装类方法重载的规则:

  1. 如果您将原始数据类型作为参数传递给方法调用,编译器首先会检查将相同数据类型作为参数的方法定义。
  2. 如果这样的方法不存在,那么它会检查一个方法定义,该定义采用比传递的数据类型更大的原始数据类型。即,它尝试对传递的数据类型执行自动扩展转换。
  3. 如果无法进行自动扩展转换,则它会检查将相应的包装类类型作为参数的方法定义。即,它尝试执行自动装箱转换。
  4. 如果这样的方法不存在,那么它会检查以超类类型(数字或对象类型)作为参数的方法。
  5. 如果这样的方法也不存在,那么编译器会给出编译时错误。

根据规则 1,它应该打印Integer Class Type. 我在这里想念什么?

标签: javawrapperautoboxing

解决方案


在语言规范级别,这是因为具有不同为原始类型和包装原始类型的参数的方法不被视为override-equivalent。(一种奇特的说法“他们只是不这样做,因为语言规范是这样说的”)。

但从逻辑上讲,它们也不应该,至少在int子类中的参数“覆盖”超类中的包装参数的情况下。

根据 Liskov 的替换原则,子类中的方法必须至少接受超类中的方法接受的所有参数。

如果超类方法接受被包装的类,它可以接受null. 如果子类方法只允许接受int,它不能接受 null,所以它是不可替代的。


推荐阅读