Scala标准库中的许多类使用其伴随对象的apply()
作为工厂。链接List(List(1))
等呼叫时,这通常很方便。另一方面,仍然可以使用new
(new HashMap[Int, Int]()
)直接创建对象。
该标准库。现在,在我自己的代码中,哪种方法更好用:伴侣工厂或用new
创建对象?
是否有关于何时创建随播对象工厂以及何时使用new
关键字的约定?
使用一个优于另一个有什么好处?
答案 0 :(得分:5)
在大多数情况下,我使用伴随对象的apply
方法,因为代码看起来不那么杂乱。但是,使用静态工厂至少有一个好处。考虑一下仅包含MyInt
的缺乏想象力的Int
类型:
class MyInt(val i: Int)
我可以获取MyInt
调用构造函数的实例,每次调用构造函数时都会实例化一个新对象。如果我的程序依赖于MyInt
,这会导致创建大量实例。假设我使用的MyInt
大部分都是-1
,0
和1
,因为MyInt
是不可变的,我可以重复使用相同的实例:
class MyInt(val i: Int)
object MyInt {
val one = new MyInt(1)
val zero = new MyInt(0)
val minusOne = new MyInt(-1)
def apply(i: Int) = i match {
case -1 => minusOne
case 0 => zero
case 1 => one
case _ => new MyInt(i)
}
}
因此,至少对于不可变值,使用静态工厂而不是调用构造函数可能具有技术优势。这意味着,如果您想在代码中表达创建新实例,请使用new
关键字。就个人而言,我在创建对象时使用new
- 关键字,在创建值时使用apply
- 方法,但我不知道是否存在官方约定。
答案 1 :(得分:3)
我不知道有一种方法的一般建议,通常只是方便不必键入new
。
但是,有时候工厂方法选项会更好。例如,如果您的类具有必须为大写的String字段,则可以使标准构造函数为private,通过factory方法强制实例化,以确保该字段始终为大写:
class A private[A] (s: String)
object A {
def apply(s: String): A = new A(s.toUpperCase)
}
注意:如果您的课程是一个案例类,那么还有其他一些调整可以让它完全发挥作用 - 请参阅here。