Java / Scala Limited generalizations and type inference mismatch

Based on the Java background, I understand that this does not compile.

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 } 

The last line causes a compiler error (EDIT: at least on jdk1.6.0_65):

Associated mismatch: the general returnSub (T, U) method of type Test is not applicable for arguments (Test.SubClass, Test.SuperClass). The deduced type Test.SuperClass is not a valid replacement for a limited parameter

So, I was surprised that this works in Scala. I wrote an example code below (which, as far as I can tell, expresses the same “logic”):

 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) } 

I think the Scala compiler is smart enough to say "OK, child is an instance of SubClass , but I can't call returnSub if I say so, so let me try if I think of child as an instance of SuperClass , and, well, it works, so let's do it. "

Is that what happens (and if so, can you point out this language specification)? Or maybe my Scala transform is not equivalent to my Java code?

Thanks!

+5
source share
1 answer

Your code should work in both languages ​​because T and U can be SuperClass . With Java 1.8, your code compiles without a problem. Type inference has improved significantly since generics were introduced, but you can make it work with all versions of Java from 1.5 years by writing

 ThisClass.<SuperClass, SuperClass>returnSub(child, parent); 

Now you need to provide explicit type arguments, as this is much less common.

As for why you don’t have the same problems with Scala, I’m afraid I can’t answer that, because I don’t know Scala at all.

+2
source

Source: https://habr.com/ru/post/1232873/


All Articles