Scala type inference error in "? Extends" in Java code

I have the following simple Java code:

package testj; import java.util.*; public class Query<T> { private static List<Object> l = Arrays.<Object>asList(1, "Hello", 3.0); private final Class<? extends T> clazz; public static Query<Object> newQuery() { return new Query<Object>(Object.class); } public Query(Class<? extends T> clazz) { this.clazz = clazz; } public <S extends T> Query<S> refine(Class<? extends S> clazz) { return new Query<S>(clazz); } public List<T> run() { List<T> r = new LinkedList<T>(); for (Object o : l) { if (clazz.isInstance(o)) r.add(clazz.cast(o)); } return r; } } 

I can call this from Java as follows:

 Query<String> sq = Query.newQuery().refine(String.class); //NOTE NO <String> 

But if I try to do the same from Scala:

 val sq = Query.newQuery().refine(classOf[String]) 

I get the following error:

error: type of mismatch
found: lang.this.class [scala.this.Predef.String]
required: lang.this.class [? 0] forSome {type? 0 <:? }
val sq = Query.newQuery (). specify (classOf [String])

This is only fixed by entering the correct type parameter!

 val sq = Query.newQuery().refine[String](classOf[String]) 

Why can't scala do this from my argument? Note. I am using Scala 2.7

+4
source share
1 answer

The output works against Scala 2.8.0.Beta1.

For earlier versions, it works if you change:

 public <S extends T> Query<S> refine(Class<? extends S> clazz) 

in

 public <S extends T> Query<S> refine(Class<S> clazz) 

scalac -print assumes that the interpretation of Java signatures has not changed in Scala versions. So the difference is probably in the type / pointer itself.

Scala 2.7.5

Original

 def refine[S >: _root_.scala.Nothing <: T](clazz: Class[_$1] forSome { type _$1 >: Nothing <: S }): Query[S] = _; 

Modified

 def refine[S >: _root_.scala.Nothing <: T](clazz: Class[S]): Query[S] = _; 

Scala 2.8.0.Beta1

Original

 def refine[S >: scala.Nothing <: T](clazz: Class[_$1] forSome { type _$1 >: Nothing <: S } = _): Query[S] = _; 

Modified

 def refine[S >: scala.Nothing <: T](clazz: Class[S] = _): Query[S] = _; 
+5
source

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


All Articles