I have a series of Java classes that acts as wrappers for java classes, e.g. Integer, String, ZonedDateTime, etc, and I put them into this Type<T>
interface, where T
is what the actual underlying Java type would be.
There's another class called: final class Field<T, U extends Type<T>>
.
Finally, I have a following builder interface.
class DataBuilder {
<T, U extends Type<T>> DataBuilder addEntry(Field<T, U> field, T value) {
return this;
}
}
This works fine calling from Java side:
public static void main(String[] args) {
Field<String, StringType> field1 = new Field<>();
Field<Boolean, BooleanType> field2 = new Field<>();
Map<Field, Object> map = new HashMap<>();
map.put(field1, "abc");
map.put(field2, true);
DataBuilder dataBuilder = new DataBuilder();
map.forEach(dataBuilder::addEntry);
System.out.println("good");
}
Calling this from Scala side causes some issue.
object Hello extends App {
val field1 = new Field[String, StringType]
val field2 = new Field[java.lang.Boolean, BooleanType]
val map = Map(
field1 -> "abc",
field2 -> boolean2Boolean(true)
)
val dataBuilder: DataBuilder = new DataBuilder
map.foreach { case (key, value) => dataBuilder.addEntry(key, value) }
}
This gives me three errors:
Error:(14, 50) inferred type arguments [Comparable[_ >: Boolean with String <: Comparable[_ >: Boolean with String <: java.io.Serializable] with java.io.Serializable] with java.io.Serializable,_2] do not conform to method addEntry's type parameter bounds [T,U <: example.Type[T]]
map.foreach { case (key, value) => dataBuilder.addEntry(key, value) }
Error:(14, 59) type mismatch;
found : example.Field[_1,_2] where type _2 >: example.BooleanType with example.StringType <: example.Type[_ >: Boolean with String <: Comparable[_ >: Boolean with String <: java.io.Serializable] with java.io.Serializable], type _1 >: Boolean with String <: Comparable[_ >: Boolean with String <: Comparable[_ >: Boolean with String <: java.io.Serializable] with java.io.Serializable] with java.io.Serializable
required: example.Field[T,U]
map.foreach { case (key, value) => dataBuilder.addEntry(key, value) }
Error:(14, 64) type mismatch;
found : Comparable[_ >: Boolean with String <: Comparable[_ >: Boolean with String <: Comparable[_ >: Boolean with String <: java.io.Serializable] with java.io.Serializable] with java.io.Serializable] with java.io.Serializable
required: T
map.foreach { case (key, value) => dataBuilder.addEntry(key, value) }
I understand that scala is trying to infer the most accurate type by trying to find a common type across all the ones in the Map, but is there a way to not make it that explicit while still allowing java library to function in scala?
See demo code in github: https://github.com/ssgao/java-scala-type-issue