Java泛型和Scala的交集是...进展不顺利

我坦率地承认,我在这里有点超出我的深度。我在类型系统上的正式培训已经过去了几十年。我在Java中相当琐碎地使用了一两次泛型,但它们并不是我可以声称对它们有深刻而透彻的理解的东西。我也是Scala的新手,所以我也不是说对它的类型系统有深入或透彻的了解。


我开始更新我的XML葫芦v2实现,用Scala(今天的2.12)编写,使用Saxon 9.9。Saxon 9.9在许多地方引入了泛型。我很好。我能应付,我想象。


除了,我显然不能。


绊脚石是尝试实现一个扩展扩展函数定义类的类。它有一个内部类,用于扩展函数调用类。反过来,它具有一个抽象方法,调用,在Java中如此定义:


public abstract Sequence<?> call(

    XPathContext context,

    Sequence[] arguments

)

我第一次尝试在Scala中定义这一点是:


override def call(

    context: XPathContext,

    arguments: Array[Sequence]

): Sequence[_]

但这不会编译:“特征序列采用类型参数”。


这是真的:


public interface Sequence<T extends Item<?>>

(顺便说一句,项目是:


public interface Item<T extends Item<?>>

extends GroundedValue<T>

由于其他原因,我发现这有点令人困惑)


对于我的第二次尝试,我尝试了:


override def call(

    context: XPathContext,

    arguments: Array[Sequence[_]]

): Sequence[_]

但是,我被告知,这并不能覆盖任何东西。哈克,编译器说:


[error] (Note that Array[net.sf.saxon.om.Sequence]

does not match Array[net.sf.saxon.om.Sequence[_]]:

their type parameters differ)

在这里,我们似乎陷入了僵局。当然,我可以在Java中实现该死的东西,但这是Scala或我的理解中的实际限制吗?


顺便说一句,我之前就在我的第一次尝试中撒谎。我的第一次尝试实际上是:


override def call(

    context: XPathContext,

    arguments: Array[Sequence[_ <: Item[_ <: Item[_]]]]

): Sequence[_ <: Item[_ <: Item[_]]]

我通过直言不讳地将Java复制到斯卡拉并让IntelliJ IDEA翻译它来制作。我未能弄清楚如何处理项目声明的递归性质。


慕后森
浏览 74回答 3
3回答

隔江千里

尝试override&nbsp;def&nbsp;call(context:&nbsp;XPathContext,&nbsp;arguments:&nbsp;Array[Sequence[_&nbsp;<:&nbsp;Item[_]]]):&nbsp;Sequence[_]&nbsp;=&nbsp;???

UYOU

这绝对是编译的(从而证实了德米特罗·米廷的提议是有效的):// ExtensionFunctionCall.javapublic interface ExtensionFunctionCall {&nbsp; Sequence<?> call(String ctx, Sequence[] args);}// Item.javapublic interface Item<T extends Item<?>> {}// Sequence.javapublic interface Sequence<T extends Item<?>> {}// Impl.scalaclass Impl extends ExtensionFunctionCall {&nbsp; override def call(&nbsp; &nbsp; ctx: String,&nbsp; &nbsp; args: Array[Sequence[_ <: Item[_]]]&nbsp; ): Sequence[_] = ???}顺便说一句,这不仅仅是斯卡拉的问题。如果你忘记了Scala一秒钟,并尝试在Java中实现它,你得到的基本上是相同的错误:class ImplJava implements ExtensionFunctionCall {&nbsp; public Sequence<?> call(&nbsp; &nbsp; String ctx,&nbsp; &nbsp; Sequence<?>[] args&nbsp; ) {&nbsp; &nbsp; return null;&nbsp; }}给:ImplJava.java:1: error: ImplJava is not abstract and does not override abstract method call(String,Sequence[]) in ExtensionFunctionCallclass ImplJava implements ExtensionFunctionCall {^ImplJava.java:2: error: name clash: call(String,Sequence<?>[]) in ImplJava and call(String,Sequence[]) in ExtensionFunctionCall have the same erasure, yet neither overrides the other&nbsp; public Sequence<?> call(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;^2 errors现在,这真的很神秘,我不知道如何在Java中写下这种类型。我不确定它是否可以在Java中表达而不恢复到1.4风格。事情是邪恶的,或者,引用德米特罗·米廷链接的这篇精彩文章:Sequence[]原始类型很糟糕。停止使用它们

拉丁的传说

我认为在java中没有类型参数可以转换为最高可能的超类型(在这种情况下)。所以,我希望这样的东西能起作用:SequenceSequence[Foo]FooItemoverride&nbsp;def&nbsp;call(context:&nbsp;XPathContext,&nbsp;arguments:&nbsp;Array[Sequence[Item[_]]]):&nbsp;Sequence[_]&nbsp;=&nbsp;???
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java