Как конвертировать Scala List [String] в legacy Java List - PullRequest
1 голос
/ 05 февраля 2020

У меня есть наследие (изменения не разрешены) Java код:

//File Foo.java
package sof;
public interface Foo<T> {}

//File Bar.java
package sof;
public class Bar implements Foo<String> {}

//File Holder.java    
package sof;
import java.util.List;
public class Holder {
    private List<Foo<?>> lst;
    public Holder() {}
    public Holder(List<Foo<?>> lst) {this.lst = lst;}
    public List<Foo<?>> getLst() {return lst;}
    public void setLst(List<Foo<?>> lst) {this.lst = lst;}
}

Теперь в моем коде Scala я хочу передать список баров в holder :

import sof._
import collection.JavaConverters._
val bar = new Bar()
val bars: java.util.List[Bar] = List(bar).asJava
val holder = new sof.Holder(bars)

Не компилируется. Ошибка:

Ошибка: (37, 18) несоответствие типов; найдено: java .util.List [ sof.Bar ] обязательно: java .util.List [ sof.Foo [_] ] Примечание: sof.Bar <: sof.Foo [_], но Java -определенная черта List является инвариантом типа E. Вы можете wi sh, чтобы исследовать подстановочный тип, такой как <code>_ <: sof.Foo[_]. (SLS 3.2.10)
новый sof.Holder (бары)

В качестве обходного пути я могу

val holder = new sof.Holder()
val tmpLst = holder.getLst
tmpLst.add(bar)

Это работает, но это ужасно. Итак, что за структура Scala подходит java.util.List<?>?

1 Ответ

3 голосов
/ 05 февраля 2020

Java хочет java.util.List<Foo<?>>, но вы даете это java.util.List<Bar>. Java не поддерживает List дисперсию, поэтому это не работает.

Вам необходимо указать фактический тип:

val bar = new Bar()
val foos: List[Foo[_]] = List(bar)
val holder = new sof.Holder(foos.asJava)
...