何时使用伴随对象工厂与 new 关键字
When to use companion object factory versus the new keyword
Scala 标准库中的许多 类 使用其伴随对象的 apply()
作为工厂。这在像 List(List(1))
这样的链接调用时通常很方便。另一方面,仍然可以直接使用 new
(new HashMap[Int, Int]()
).
创建对象
那是标准库。现在,在我自己的代码中,哪种方法更适合使用:配套工厂还是使用 new
?
创建对象
关于何时创建伴生对象工厂以及何时使用 new
关键字是否有约定?
使用一个比另一个有什么优势?
我不知道是否有一种方法优于另一种方法的一般建议,通常只是为了方便而不必键入 new
。
不过,在某些情况下,工厂方法选项可能会更好。例如,如果您的 class 有一个必须为大写的 String 字段,您可以将标准构造函数设为私有,通过确保该字段始终为大写的工厂方法强制实例化:
class A private[A] (s: String)
object A {
def apply(s: String): A = new A(s.toUpperCase)
}
注意:如果您的 class 是 class 的情况,还有其他一些调整可以使其完全正常工作 - 请参阅 。
在大多数情况下,我使用伴随对象的 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
-方法,尽管我不知道是否有官方约定。
Scala 标准库中的许多 类 使用其伴随对象的 apply()
作为工厂。这在像 List(List(1))
这样的链接调用时通常很方便。另一方面,仍然可以直接使用 new
(new HashMap[Int, Int]()
).
那是标准库。现在,在我自己的代码中,哪种方法更适合使用:配套工厂还是使用 new
?
关于何时创建伴生对象工厂以及何时使用 new
关键字是否有约定?
使用一个比另一个有什么优势?
我不知道是否有一种方法优于另一种方法的一般建议,通常只是为了方便而不必键入 new
。
不过,在某些情况下,工厂方法选项可能会更好。例如,如果您的 class 有一个必须为大写的 String 字段,您可以将标准构造函数设为私有,通过确保该字段始终为大写的工厂方法强制实例化:
class A private[A] (s: String)
object A {
def apply(s: String): A = new A(s.toUpperCase)
}
注意:如果您的 class 是 class 的情况,还有其他一些调整可以使其完全正常工作 - 请参阅
在大多数情况下,我使用伴随对象的 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
-方法,尽管我不知道是否有官方约定。