在 Scala 中使用 Java 类 的有界通配符编译错误
Compilation error with bounded wildcards using Java classes in Scala
在Java中,我们这样定义了一个ObservableCollection.java
:
public class ObservableCollection<T> implements Collection<T> {
public SubscriptionHandle onElementAdded(Consumer<T> onAdded) {
// ...
}
}
还有一个 AgentService.java
,returns 一个 ObservableCollection:
public interface AgentService {
ObservableCollection<? extends Agent> getAgents();
}
现在,我正尝试在 Scala 项目中使用这个 ObservableCollection.java
,如下所示:
def test(service: AgentService): Unit = {
val onAdded: Consumer[_ <: Agent] = ???
service.getAgents.onElementAdded(onAdded)
}
尝试此操作会导致以下编译错误:
type mismatch;
found : java.util.function.Consumer[_] where type _ <: com.xxxx.xx.xx.agent.Agent
required: java.util.function.Consumer[?0] where type ?0 <: com.xxxx.xx.xx.agent.Agent
service.getAgents.onElementAdded(onAdded)
^
one error found
这对我来说意义不大。有什么办法可以得到这个 运行?
编辑: 使用 Cosumer[Agent]
导致以下错误:
type mismatch;
found : java.util.function.Consumer[com.xxxx.xx.xx.agent.Agent]
required: java.util.function.Consumer[?0] where type ?0 <: com.kuka.cc.si.agent.Agent
Note: com.xxxx.xx.xx.agent.Agent >: ?0, but Java-defined trait Consumer is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: ?0`. (SLS 3.2.10)
service.getAgents.onElementAdded(onAdded)
^
one error found
这件事不在 Scala-Java 互操作中。以下 Scala 代码也无法编译
import java.util.function.Consumer
import java.util
trait Agent
trait SubscriptionHandle
trait AgentService {
def getAgents: ObservableCollection[_ <: Agent]
}
trait ObservableCollection[T] extends util.Collection[T] {
def onElementAdded(onAdded: Consumer[T]): SubscriptionHandle
}
def test(service: AgentService): Unit = {
val onAdded: Consumer[_ <: Agent] = ???
val agents: ObservableCollection[_ <: Agent] = service.getAgents
agents.onElementAdded(onAdded)
// ^^^^^^^
}
//type mismatch;
// found : java.util.function.Consumer[_] where type _ <: App.Agent
// required: java.util.function.Consumer[_]
你误用了存在类型(通配符泛型)。以下代码无法编译
trait X[T]
trait Y[T] {
def foo(x: X[T]) = ???
}
val x: X[_] = ???
val y: Y[_] = ???
y.foo(x) // doesn't compile
x
和 y
都具有存在类型,但 foo
接受类型 X[T]
的 x
,其中 T
必须相同因为 T
在 y
的类型中,即 Y[T]
,所以你不能保证 T
是相同的。
修复编译的一种方法是将泛型添加到 AgentService
trait Agent
trait SubscriptionHandle
trait AgentService[T <: Agent] {
def getAgents: ObservableCollection[T]
}
trait ObservableCollection[T] extends util.Collection[T] {
def onElementAdded(onAdded: Consumer[T]): SubscriptionHandle
}
def test[T <: Agent](service: AgentService[T]): Unit = {
val onAdded: Consumer[T] = ???
val agents: ObservableCollection[T] = service.getAgents
agents.onElementAdded(onAdded)
}
或其方法
trait Agent
trait SubscriptionHandle
trait AgentService {
def getAgents[T <: Agent]: ObservableCollection[T]
}
trait ObservableCollection[T] extends util.Collection[T] {
def onElementAdded(onAdded: Consumer[T]): SubscriptionHandle
}
def test[T <: Agent](service: AgentService): Unit = {
val onAdded: Consumer[T] = ???
val agents: ObservableCollection[T] = service.getAgents
agents.onElementAdded(onAdded)
}
在Java中,我们这样定义了一个ObservableCollection.java
:
public class ObservableCollection<T> implements Collection<T> {
public SubscriptionHandle onElementAdded(Consumer<T> onAdded) {
// ...
}
}
还有一个 AgentService.java
,returns 一个 ObservableCollection:
public interface AgentService {
ObservableCollection<? extends Agent> getAgents();
}
现在,我正尝试在 Scala 项目中使用这个 ObservableCollection.java
,如下所示:
def test(service: AgentService): Unit = {
val onAdded: Consumer[_ <: Agent] = ???
service.getAgents.onElementAdded(onAdded)
}
尝试此操作会导致以下编译错误:
type mismatch;
found : java.util.function.Consumer[_] where type _ <: com.xxxx.xx.xx.agent.Agent
required: java.util.function.Consumer[?0] where type ?0 <: com.xxxx.xx.xx.agent.Agent
service.getAgents.onElementAdded(onAdded)
^
one error found
这对我来说意义不大。有什么办法可以得到这个 运行?
编辑: 使用 Cosumer[Agent]
导致以下错误:
type mismatch;
found : java.util.function.Consumer[com.xxxx.xx.xx.agent.Agent]
required: java.util.function.Consumer[?0] where type ?0 <: com.kuka.cc.si.agent.Agent
Note: com.xxxx.xx.xx.agent.Agent >: ?0, but Java-defined trait Consumer is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: ?0`. (SLS 3.2.10)
service.getAgents.onElementAdded(onAdded)
^
one error found
这件事不在 Scala-Java 互操作中。以下 Scala 代码也无法编译
import java.util.function.Consumer
import java.util
trait Agent
trait SubscriptionHandle
trait AgentService {
def getAgents: ObservableCollection[_ <: Agent]
}
trait ObservableCollection[T] extends util.Collection[T] {
def onElementAdded(onAdded: Consumer[T]): SubscriptionHandle
}
def test(service: AgentService): Unit = {
val onAdded: Consumer[_ <: Agent] = ???
val agents: ObservableCollection[_ <: Agent] = service.getAgents
agents.onElementAdded(onAdded)
// ^^^^^^^
}
//type mismatch;
// found : java.util.function.Consumer[_] where type _ <: App.Agent
// required: java.util.function.Consumer[_]
你误用了存在类型(通配符泛型)。以下代码无法编译
trait X[T]
trait Y[T] {
def foo(x: X[T]) = ???
}
val x: X[_] = ???
val y: Y[_] = ???
y.foo(x) // doesn't compile
x
和 y
都具有存在类型,但 foo
接受类型 X[T]
的 x
,其中 T
必须相同因为 T
在 y
的类型中,即 Y[T]
,所以你不能保证 T
是相同的。
修复编译的一种方法是将泛型添加到 AgentService
trait Agent
trait SubscriptionHandle
trait AgentService[T <: Agent] {
def getAgents: ObservableCollection[T]
}
trait ObservableCollection[T] extends util.Collection[T] {
def onElementAdded(onAdded: Consumer[T]): SubscriptionHandle
}
def test[T <: Agent](service: AgentService[T]): Unit = {
val onAdded: Consumer[T] = ???
val agents: ObservableCollection[T] = service.getAgents
agents.onElementAdded(onAdded)
}
或其方法
trait Agent
trait SubscriptionHandle
trait AgentService {
def getAgents[T <: Agent]: ObservableCollection[T]
}
trait ObservableCollection[T] extends util.Collection[T] {
def onElementAdded(onAdded: Consumer[T]): SubscriptionHandle
}
def test[T <: Agent](service: AgentService): Unit = {
val onAdded: Consumer[T] = ???
val agents: ObservableCollection[T] = service.getAgents
agents.onElementAdded(onAdded)
}