我怀疑伴随对象中的工厂方法是你能做的最好的(如wheaties
建议的那样)。我们可以让它编译,但代价是愚蠢。例如:
final case class C[A] (v: A) {
def this() = this("Hello".asInstanceOf[A]) // Compiles, thanks to type erasure
}
val c = new C[Int]() // Still compiles, despite the fact that "Hello" is not an Int
println(c) // C(Hello)
c.v + 1 // Compiles, but throws a ClassCastException at run-time
基本问题是类型参数是在类级别指定的,而不是构造函数级别,因此所有构造函数都必须使用相同的类型参数。另一方面,方法可以接受类型参数,所以工厂方法没有问题。此外,工厂方法的 Java 互操作也不是那么糟糕。您可以执行以下操作:
// C.scala
final case class C[A] (v: A)
object C {
def apply(): C[Boolean] = C(true)
}
// Test.java
public class Test {
public C c = C.apply();
}
scala 编译器创建静态方法来简化 Java 互操作,因此您通常不需要弄乱C$
.