从Scala访问参数化Java类的静态方法

时间:2016-05-11 23:55:43

标签: java scala

在Scala中,我正在做一些Java互操作。我正在创建类Sample.Individual的值,我正在调用像Sample.Individual.newBuilder()这样的静态Java方法。我使用的是几个都具有相同静态方法的类(例如:Sample.PositionSample.Feature)。我想创建一个对它们进行参数化的函数,例如:

def p[T](s: String): T = {
    val pb = T.newBuilder() // this returns a value of type T.Builder
    ... do stuff with pb ...
    pb.build() // this returns a value of type T
}

但这告诉我“找不到:价值T”

参数化类型Sample.Individual的正确方法是什么,让我也可以从Scala中调用其中包含的静态方法?

1 个答案:

答案 0 :(得分:1)

我强烈建议你不要继续这个想法。即使你找到了一种方法,它也不是惯用的Scala。你可以远程地删除几行代码,但是你的可读性和性能都有所下降;糟糕的权衡。

您遇到的问题是,您为p函数提供了类型参数T,然后在该类型newBuilder上调用T方法。你不能这样做,因为Scala对你的类型T一无所知。

相反,首先要了解有关这些Java类型的更多信息。是否所有可能构造的类都扩展了一个共同的类型?如果没有,你运气不好(如果你选择皮条客你正在使用的图书馆,你在技术上并不是运气不好,但请不要:P)。

否则,只需导入这些类型(包括通用类型)。将泛型类型作为p函数的类型并匹配字符串,然后只是实例化您的类型。字符串可以是任何内容,因此您可能希望返回Option[GenericClass]而不是GenericClass

e.g。

import xxx.GenericClassBuilder
import xxx.GenericClass
import xxx.ClassA
import xxx.ClassB

def p(s: String): Option[GenericClass] = {
   val maybePb: Option[GenericClassBuilder] = s match {
      case "ClassA" => Some(ClassA.newBuilder())
      case "ClassB" => Some(ClassB.newBuilder())
      case _ => None
   }
   maybePb.foreach { pb => ... do side-effecty stuff with pb ...}
   maybePb.map(_.build())
}