0

I'm writing a framework. The interfaces are written and compiled in Java code. The client uses Scala and those interfaces. Here is an example of the interface.

public interface Context {
   MyComponent<? extends File> getComponent();
}

Now my scala code uses the interface as follows.

val component = context.getComponent();
println(calculate(component));

def calculate( component: MyComponent[File] ): Unit = ???

Scala compiler is throwing errors at line 2 for println(calculate(component)). The error is: Type mismatched, expected: MyComponent[File], actual: MyComponent[_ <: File].

Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93
TrongBang
  • 923
  • 1
  • 12
  • 23
  • That's because `? extends File` corresponds to the existential type `_ <: File` in Scala. So, what happens if you replace `def calculate( component: MyComponent[File] ): Unit = ???` by `def calculate(component: MyComponentFile[_ <: File]): Unit = ???`, as the error message suggests? – Andrey Tyukin May 22 '18 at 01:46
  • 1
    @AndreyTyukin: you are right. Thanks man. Just got back to Scala after long time. Really didn't think of that. – TrongBang May 22 '18 at 02:27

1 Answers1

1

Java's wildcard type

? extends File

corresponds to the existential type

_ <: File

in Scala. Try changing the signature

def calculate(component: MyComponent[File]): Unit = ???

to

def calculate(component: MyComponent[_ <: File]): Unit = ???

Also note that if MyComponent were a Scala-class that is under your control, then changing the invariant type parameter to covariant type parameter +F might also work, because then every MyComponent[F] forSome { type F <: File } would be a special case of MyComponent[File].

Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93