Wins
Wins

Reputation: 3460

Scala calling Java method with array parameter

Supposed I have a Java API like below:

public class JavaApi<T> {
    public void foo(T[] data) {
        ...
    }
}

And I'd like to call it from Scala with the following class:

class Caller[T] {
    val javaApi = new JavaApi[T]()

    def callApi(data: Array[T]) = javaApi.foo(data)
}

On compile, I get the following:

type mismatch;
found   : Array[T]
required: Array[T with Object]
Note: T >: T with Object, but class Array is invariant in type T.
You may with to investigate a wildcard type such as `_ >: T with Object`. (SLS 3.2.10)
  def callApi(data: Array[T]) = javaApi.foo(data)

Upvotes: 1

Views: 4022

Answers (2)

chengpohi
chengpohi

Reputation: 14217

This is caused by Java does not support polymorphic of primitive type.

Although Scala deal anything as Object but after compiler compile, maybe it will convert object to primitive type arrays for performance, such as:

scala> var a = Array(1, 2, 3)
a: Array[Int] = Array(1, 2, 3)
scala> :javap -c a
public class $line3.$read$$iw$$iw$ {
  ...
  public int[] a();
  ...

As you can see, the above Array[Int] has been convert to int[] primitive type arrays.

so for this reason, this maybe cause incompatible for Java method.

Solution:

  1. As @Jubobs said, bound T to T <: AnyRef. as val a = Array[Integer](1, 2, 3), the compiler will deal it as Integer[] type.
  2. Use List to replace Array,List always reference type.

Reference:

https://issues.scala-lang.org/browse/SI-750

Upvotes: 0

borjab
borjab

Reputation: 11655

You may review the Scala type hierarchy. More specifically the phrase:

If Scala is used in the context of a Java runtime environment, then scala.AnyRef corresponds to java.lang.Object

So, by changing it as Jubobs suggested you are sure that the type correspond to an object:

class Caller[T<: AnyRef] {
    val javaApi = new JavaApi[T]()

    def callApi(data: Array[T]) = javaApi.foo(data)
}

So if you need any value type like int, char, boolean you will need to convert them to their object equivalent boxed Java type like Integer, Character or Boolean. See: enter image description here

Upvotes: 1

Related Questions