3

I'm trying to declare a method in an abstract class which receives an Array of generic type T. As such:

abstract class Circle[-T] extends Shape[T] {
   def draw(points: Array[T]): Unit
}

The problem I'm getting is that Scala compiler complaints with:

contravariant type T occurs in invariant position in type Array[T] of value points

So, is there anyway to solve this besides the following?

def draw[U <: T](points: Array[U]): Unit

As a note, I also need to extend this class in Java.

2 Answers 2

4

Scala's Array maps directly to Java arrays, and is invariant ([T] instead of [+T])

Array is a tricky beast. It's about the only thing that gets reified on the JVM, and it's common knowledge that array variance is purposely broken so that methods like Arrays.sort() could be implemented.

You'd probably be better off using a "true" Java collection here.

To answer the more general question: Yes, if you want to use a parametrised invariant type in a method of a contra-variant class, you have to specify an upper bound in the signature for that method

Sign up to request clarification or add additional context in comments.

1 Comment

Note that Java arrays are covariant, weird as that might seem. Scala's invariantness results in some problems, particularly with methods expecting Object[].
3

Related to this question. You can either skip check for variance

scala> import scala.annotation.unchecked.uncheckedVariance
import scala.annotation.unchecked.uncheckedVariance

scala> abstract class Circle[-T] extends Shape[T @uncheckedVariance] {
     |    def draw(points: Array[_<:T]): Unit
     | }
defined class Circle

or use a view bound

scala> abstract class Circle[T<%T] extends Shape[T]{
     | def draw(points: Array[_<:T]): Unit
     | }
defined class Circle

3 Comments

@missingfactor huh, scala has too much to offer :)
Hm, although it compiles, when calling the draw method from Java I get the following error: Circle: method <init>()V not found
@halfwarp did you use the annotation or view bounds?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.