GPI*_*GPI 5 java generics scala
来自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
}
Run Code Online (Sandbox Code Playgroud)
最后一行产生编译器错误(编辑:至少在jdk1.6.0_65上),它确实:
绑定不匹配:类型Test的泛型方法returnSub(T,U)不适用于参数(Test.SubClass,Test.SuperClass).推断类型Test.SuperClass不是有界参数的有效替代
所以,我很惊讶,这似乎在Scala中起作用.我在下面编写了示例代码(据我所知,表达了相同的"逻辑"):
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)
}
Run Code Online (Sandbox Code Playgroud)
我猜 Scala编译器很聪明,可以说"好吧,child是一个实例SubClass,但returnSub如果我这样说就不能调用,所以如果我考虑child作为一个SuperClass实例,让我试试,好吧,它有用,所以让我们做那".
这是发生了什么(如果是这样,你能指出一个语言规范)吗?或者我的Scala"转换"可能不等同于我的Java代码?
谢谢!
您的代码应该适用于两种语言,因为T和U都可以是SuperClass. 使用 Java 1.8,您的代码可以毫无问题地编译。自从引入泛型以来,类型推断已经有了很大的改进,但是您可以通过编写以下代码来使其适用于从 1.5 开始的所有 Java 版本
ThisClass.<SuperClass, SuperClass>returnSub(child, parent);
Run Code Online (Sandbox Code Playgroud)
现在,您需要提供这样的显式类型参数的频率要少得多。
至于为什么你在 Scala 上没有遇到同样的问题,恐怕我无法回答,因为我根本不了解 Scala。
| 归档时间: |
|
| 查看次数: |
171 次 |
| 最近记录: |