在获取参数化类型时,java似乎选择了重载的具体类型

时间:2015-07-11 22:29:41

标签: java generics types overloading parameterized

我遇到了以下问题:我已经重载方法doSomething(),该方法需要BooleanObject,我会调用returnSomething()并通过将值返回doSomething(),如下面的代码段所示:

public class SomeService {
    public <T> T returnSomething() {
        return null;
    }

    public void doSomething(Boolean a) {
       System.out.println("Boolean");
    }

    public void doSomething(Object a) {
        System.out.println("object");
    }

    public static void main(String[] args) {
        SomeService someService = new SomeService();
        someService.doSomething(someService.returnSomething()); // prints Boolean
    }
}

当我运行代码时,它会调用doSomething((Boolean))

由于returnSomething()的返回类型被删除为Object,我原以为它会调用doSomething((Object))

是否有人知道这是否是它调用doSomething((Boolean))而不是doSomething((Object))的预期行为?

我试图改变这两种方法的顺序,看看是否重要,但它没有。我还尝试将Boolean参数更改为Integer,它确实以相同的方式运行,即它调用非对象方法。

作为奖励信息,我还发现我是否添加了其他方法doSomething((Integer))

  • IntelliJ 14返回以下错误消息:cannot resolve method doSomething(java.lang.Object)
  • Eclipse Mars返回以下错误消息:the method doMethod(Boolean) is ambiguous for the type SomeService

如果我更改了doSomething((Integer))doSomething((Boolean))定义的顺序,则错误消息也会更改。

public class SomeService {
    public <T> T returnSomething() {
        return null;
    }

    public void doSomething(Boolean a) {
       System.out.println("Boolean");
    }

    public void doSomething(Integer a) {
       System.out.println("Integer");
    }

    public void doSomething(Object a) {
        System.out.println("object");
    }

    public static void main(String[] args) {
        SomeService someService = new SomeService();
        someService.doSomething(someService.returnSomething()); // compilation error
    }
}

1 个答案:

答案 0 :(得分:0)

此行为的原因是由于通用返回类型。

public <T> T returnSomething() {
    return null;
}

将从类型系统的角度“返回”任何类型,如果可能,将始终选择最具体的类型。这就是原因:

  1. 它将在第一个示例中选择BooleanBoolean是比Object更具体的类型)
  2. 将不会在您的第二个示例中进行编译(BooleanInteger不在同一类型层次结构中,因此没有一个更具体)