Java / Scala有界泛型和类型推断不匹配

时间:2015-10-03 22:18:58

标签: java scala generics

来自Java背景,我知道这不会编译。

public static class SuperClass {}
public static class SubClass extends SuperClass {}

public static <T, U extends T> U returnSub(T sup, U sub) {
    return sub;
}

public static void main(String[] args) {
    SuperClass parent = new SuperClass();
    SubClass child = new SubClass();

    returnSub(parent, child);
    returnSub(child, parent); // Java doesn't like that
}

最后一行产生编译错误(编辑:至少在jdk1.6.0_65上)它确实:

  

绑定不匹配:类型Test的泛型方法returnSub(T,U)不适用于参数(Test.SubClass,Test.SuperClass)。推断类型Test.SuperClass不是有界参数

的有效替代

所以,我很惊讶,这似乎适用于Scala。我在下面编写了示例代码(据我所知,表达了相同的&#34;逻辑&#34;):

class SuperClass
class SubClass extends SuperClass

def returnSub[Type, SubType <: Type](supArg: Type, subArg: SubType): SubType = {
  subArg
}

override def main(args: Array[String]): Unit = {
  val parent = new SuperClass()
  val child = new SubClass()

  val iAmOkWithThat: SubClass = returnSub(parent, child)
  val iDontGetThat: SuperClass = returnSub(child, parent)
}

猜测 Scala编译器足够聪明,可以说&#34;好的,childSubClass的一个实例,但是我无法调用{ {1}}如果我这样说,那么,如果我将returnSub视为child个实例,那么让我试一试吧,好吧,它有效,所以让我们这样做&#34;。< / p>

这是怎么回事(如果是的话,你能指出一个关于那个的语言规范)吗?或许我的Scala&#34;转换&#34;是不是等同于我的Java代码?

谢谢!

1 个答案:

答案 0 :(得分:2)

您的代码应该适用于这两种语言,因为TU都可以SuperClass。使用Java 1.8,您的代码可以毫无问题地编译。自引入泛型以来,类型推断已经大大改进,但是你可以通过编写

从1.5开始使用它来处理所有版本的Java
ThisClass.<SuperClass, SuperClass>returnSub(child, parent);

你现在需要提供这样的显式类型参数。

至于为什么你没有得到Scala的相同问题,我担心我无法回答这个问题,因为我根本不了解Scala。< / p>