【问题标题】:How to convert Scala List[String] to legacy Java List<?>如何将 Scala List[String] 转换为旧版 Java List<?>
【发布时间】:2020-05-21 07:42:08
【问题描述】:

我有旧版(不允许修改)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 代码中,我想将 bars 列表传递给 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 e>_ <: sof.Foo[_]。 (SLS 3.2.10)
新的sof.Holder(条)

作为一种解决方法,我可以

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

它有效,但很糟糕。 那么,适合 java.util.List&lt;?&gt; 的 Scala 结构是什么?

【问题讨论】:

  • 问题在于没有将 Scala List 转换为 Java 之一。你已经有了。问题在于,因为 Java 不提供对 variance 的控制,所以 j.u.List&lt;Bar&gt; 不是 j.u.List&lt;Foo&lt;?&gt;&gt; 的子类型。您可以在调用 asJava 之前尝试向上转换,这样的东西应该可以工作:val bars = (List(bar) : List[String]).asJava
  • 您的代码或错误中没有任何java.util.List&lt;?&gt;
  • @LuisMiguelMejíaSuárez 不幸的是,它以“无法将 List[Bar] 向上转换为 List[String]”而告终。是的,这是有道理的:确实,Bar 列表不是 String 列表。
  • @Lopotun O,抱歉打错了,我在手机上。应该是 val bars = (List(bar) : List[Foo[String]]).asJava 因为 BarFoo[String]
  • @Jasper-M 恐怕我不太明白你的回答。给定的 Java 代码是旧代码,我无法更改。

标签: java scala generics bounded-wildcard


【解决方案1】:

Java 想要java.util.List&lt;Foo&lt;?&gt;&gt;,但你给了它java.util.List&lt;Bar&gt;。 Java 不支持List 变化,所以这不起作用。

你需要给它它想要的实际类型:

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

【讨论】:

  • 相同(几乎)错误。现在它不会将 sof.Foo[String] 转换为 sof.Foo[] Error:(45, 38) type mismatch;找到:java.util.List[sof.Foo[String]] 需要:java.util.List[sof.Foo[]] 注意:sof.Foo[String] <: sof.foo java list e>_ <: sof.Foo[_]。 (SLS 3.2.10) val holder = new sof.Holder(foos.asJava)
  • @Lopotun 你确定你有foos: List[Foo[_]] 而不是foos: List[Foo[String]]?这将产生您显示的错误消息。
  • @AlexeyRomanov 宾果游戏!你是对的。这是我的拼写错误,List[Foo[_]] 完美运行。现在,轮到我了解它为什么以及如何工作了 :-)
  • @Lopotun 这不是你的错字,答案是在你第一次发表评论后更新的,所以你当时是正确的。 Jasper-M 在您发表评论后帮助将答案更新为正确的答案。
  • @Tim 是的,我现在看到了。它有效,这是主要的。我知道我应该修改答案:它们可能会改变:-)
猜你喜欢
  • 2020-01-11
  • 2021-09-17
  • 2016-08-22
  • 2018-02-20
  • 1970-01-01
  • 2022-01-05
  • 2019-09-10
  • 2021-08-08
  • 1970-01-01
相关资源
最近更新 更多