繁体   English   中英

如何在Scala中扩展包含泛型方法的Java接口?

[英]How do I extend Java interface containing generic methods in Scala?

假设我们有以下Java接口:

// Java
public interface Foo {
    <T> T bar(Class<T> c);
}

我应该如何在Scala中扩展它? 写作

// Scala
class FooString extends Foo {
  override def bar(c: Class[String]): String = "hello, world";
}

将导致编译器抛出“类FooString需要是抽象的,因为类型为[T ] (Class [T])T的特征Foo中的方法栏未定义。”

提前致谢!

更新:丑陋的事实是:我误解了Java中的泛型。

在任何情况下,我的困境的解决方案都显示在尼古拉斯和沃尔特的答案中,尽管我更喜欢沃尔特的答案,因为它不那么冗长。

它不起作用,因为您没有正确实现接口。 你的方法n scala的siganture必须是:

def bar[T](c:Class[T]):T

只有当你想要吨实现Foo时,你才能修复String的行为。

根据我们的讨论,第三次尝试:

def bar[T](c:Class[T]):T = {
  // Some stuff
  val o:Any = myUntypedFunction(env)
  c.cast(o)
}

根据上下文,myUntypedFunction将创建一个对象,然后使用class参数来转换结果并获取T对象。 再一次:这种行为在java和scala中是相同的。

这有效:

class FooString extends Foo {
  def bar[String](c: Class[String]): String = "hello world".asInstanceOf[String]
}

val fs = new FooString
println(fs.bar(classOf[String]))

编辑:

来自@Eastsun的评论是正确的。 由于bar是类型参数为T的泛型方法,因此Scala中bar的实现也必须是通用方法。 我认为在Scala中实现Foo的正确方法如下:

class FooString extends Foo {
  def bar[T](c: Class[T]): T = c.newInstance.asInstanceOf[T] // c gotta have a default constructor
}

val fs = new FooString
println(fs.bar(classOf[String]).getClass) // prints "class java.lang.String"
println(fs.bar(classOf[java.util.Date]).getClass) // prints "class java.util.Date"

你可能会这样改变:

public interface Foo<T> {
    T bar(Class<T> c);
}

class FooString extends Foo[String] {
    override def bar(c: Class[String]): String = "hello, world";
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM