Как преобразовать Scala List [String] в устаревший список Java List ‹?›

У меня есть устаревший (без изменений) 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 я хочу передать список полос в держатель:

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 trait List инвариантен для типа E. Возможно, вы захотите изучить подстановочный тип, такой как _ <: sof.Foo[_]. (SLS 3.2.10)
новый мягкий держатель (стержни)

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

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

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


person Lopotun    schedule 05.02.2020    source источник
comment
Проблема не в преобразовании Scala List в Java. Это у вас уже есть. Проблема в том, что поскольку Java не обеспечивает контроль над дисперсией, j.u.List<Bar> не является подтипом j.u.List<Foo<?>>. Вы можете попробовать преобразование вверх перед вызовом asJava, что-то вроде этого должно сработать: val bars = (List(bar) : List[String]).asJava   -  person Luis Miguel Mejía Suárez    schedule 05.02.2020
comment
У вас нет java.util.List<?> в вашем коде или ошибке.   -  person Jasper-M    schedule 05.02.2020
comment
@ LuisMiguelMejíaSuárez К сожалению, это заканчивается ошибкой компиляции Cannot upcast List [Bar] to List [String]. И да, это имеет смысл: действительно, список Bar не является списком String.   -  person Lopotun    schedule 05.02.2020
comment
@Lopotun О, извините за опечатку, я был в мобильном телефоне. Это должно было быть val bars = (List(bar) : List[Foo[String]]).asJava, потому что Bar - это Foo [String].   -  person Luis Miguel Mejía Suárez    schedule 05.02.2020
comment
@ Jasper-M Боюсь, я не совсем понял твой ответ. Данный код Java является устаревшим, и я не могу его изменить.   -  person Lopotun    schedule 05.02.2020
comment
@ LuisMiguelMejíaSuárez благодарит за ответ. Теперь та же проблема, но уже на уровне построения: Ошибка: (44, 18) несоответствие типов; найдено: java.util.List [sof.Foo [String]] Требуется: java.util.List [sof.Foo [_]] Примечание: sof.Foo [String] ‹: sof.Foo [_], но Java- Список определенных характеристик инвариантен для типа E. Возможно, вы захотите изучить подстановочный тип, такой как _ <: sof.Foo[_]. (SLS 3.2.10) новый мягкий держатель (стержни)   -  person Lopotun    schedule 06.02.2020


Ответы (1)


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)
person Tim    schedule 05.02.2020
comment
Такая же (почти) ошибка. Теперь он не будет преобразовывать sof.Foo [String] в sof.Foo [] Ошибка: (45, 38) несоответствие типов; найдено: java.util.List [sof.Foo [String]] требуется: java.util.List [sof.Foo []] Примечание: sof.Foo [String] ‹: sof.Foo [_], но определенный Java trait List инвариантен для типа E. Возможно, вы захотите изучить подстановочный тип, такой как _ <: sof.Foo[_]. (SLS 3.2.10) val Holder = новый sof.Holder (foos.asJava) - person Lopotun; 05.02.2020
comment
@Lopotun Вы уверены, что у вас foos: List[Foo[_]], а не foos: List[Foo[String]]? Это приведет к появлению сообщения об ошибке, которое вы показываете. - person Alexey Romanov; 05.02.2020
comment
@AlexeyRomanov Бинго! Да, ты прав. Это были мои опечатки, и List [Foo [_]] работает отлично. Теперь моя очередь разбираться, почему и как это работает :-) - person Lopotun; 06.02.2020
comment
@Lopotun Это была не ваша опечатка, ответ был обновлен после вашего первого комментария, так что в то время вы были правы. Jasper-M услужливо обновил ответ на правильный после вашего комментария. - person Tim; 06.02.2020
comment
@ Тим Да, теперь я это вижу. Работает и это главное. И я узнал, что надо пересмотреть ответы: их можно изменить :-) - person Lopotun; 06.02.2020