所有其他解决方案都是Any
to Any
,这对于像 Scala 这样的强类型语言来说是非常糟糕的。
这是一个尽可能多地保留类型的解决方案:
trait AsJava[T, R] {
def apply(o: T): R
}
object AsJava extends LowPriorityAsJava {
implicit class RecursiveConverter[T](o: T) {
def asJavaRecursive[R](implicit asJava: AsJava[T, R]): R = asJava(o)
}
implicit lazy val longAsJava: AsJava[Long, lang.Long] = new AsJava[Long, lang.Long] {
def apply(o: Long): lang.Long = Long.box(o)
}
implicit lazy val intAsJava: AsJava[Int, lang.Integer] = new AsJava[Int, lang.Integer] {
def apply(o: Int): lang.Integer = Int.box(o)
}
implicit lazy val doubleAsJava: AsJava[Double, lang.Double] = new AsJava[Double, lang.Double] {
def apply(o: Double): lang.Double = Double.box(o)
}
implicit def mapAsJava[K, V, KR, VR](
implicit
keyAsJava: AsJava[K, KR],
valueAsJava: AsJava[V, VR]
): AsJava[Map[K, V], util.Map[KR, VR]] =
new AsJava[Map[K, V], util.Map[KR, VR]] {
def apply(map: Map[K, V]): util.Map[KR, VR] =
map.map { case (k, v) => (keyAsJava(k), valueAsJava(v)) }.asJava
}
implicit def seqAsJava[V, VR](implicit valueAsJava: AsJava[V, VR]): AsJava[Seq[V], util.List[VR]] =
new AsJava[Seq[V], util.List[VR]] {
def apply(seq: Seq[V]): util.List[VR] = seq.map(valueAsJava(_)).asJava
}
implicit def setAsJava[V, VR](implicit valueAsJava: AsJava[V, VR]): AsJava[Set[V], util.Set[VR]] =
new AsJava[Set[V], util.Set[VR]] {
def apply(set: Set[V]): util.Set[VR] = set.map(valueAsJava(_)).asJava
}
implicit lazy val anyAsJava: AsJava[Any, AnyRef] = new AsJava[Any, AnyRef] {
def apply(o: Any): AnyRef = o match {
case x: Map[Any, Any] => mapAsJava(anyAsJava, anyAsJava)(x)
case x: Seq[Any] => seqAsJava(anyAsJava)(x)
case x: Set[Any] => setAsJava(anyAsJava)(x)
case x: Long => longAsJava(x)
case x: Int => intAsJava(x)
case x: Double => doubleAsJava(x)
case x => x.asInstanceOf[AnyRef]
}
}
}
trait LowPriorityAsJava {
implicit def otherAsJava[T]: AsJava[T, T] = new AsJava[T, T] {
def apply(o: T): T = o
}
}
用法:
Seq(Seq.empty[Int]).asJavaRecursive