Java构造函数和静态方法

ram*_*ram 16 java

我何时应该使用构造函数,何时应该使用静态方法?

你能用小片段解释一下吗?我浏览了几个线程,但我仍然不清楚这一点.

Ioa*_*oan 20

Joshua Bloch建议采用静态工厂方法而不是构造函数(我认为这是一种很好的做法).优点和缺点:

静态工厂方法的优点:

  • 与构造函数不同,它们有名称
  • 与构造函数不同,它们不需要在每次调用时创建新对象(您可以缓存实例:例如 Boolean.valueOf(..)
  • 与构造函数不同,它们可以返回其返回类型的任何子类型的对象(极大的灵活性)

静态工厂方法的缺点:

  • 它们并不是真正与其他静态方法不相容(如果您不熟悉API,很难找到如何初始化对象)
  • 主要的缺点(如果你只使用静态工厂方法,并使构造函数成为私有)是你不能继承该类.


Pet*_*rey 19

当您只想返回一个类型的新对象并且想要简单时,请使用公共构造函数.

一个很好的例子是StringBuilder,因为它是可变的,你可能每次都想要一个新对象.

public String toString() {
    StringBuilder sb = new StringBuilder();
    // append fields to the sb
    return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

当您可能想要重用对象时使用静态因子方法(特别是如果不可变),您可能想要返回子类或者您想要describeice构造.一个很好的例子是EnumSet,它有许多静态工厂,即使有些工具具有相同的参数,它们也会做不同的事情.

EnumSet.noneOf(RetentionPolicy.class);
// has the same arguments, but is not the same as
EnumSet.allOf(RetentionPolicy.class);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,使用静态工厂可以清楚地了解这两种构造方式之间的区别.

此外,EnumSet可以返回两个不同的实现,一个针对具有少量值(<= 64)的枚举进行优化RegularEnumSet,另一个针对多个值进行调优JumboEnumSet

  • 我实际上声称StringBuilder是一个很好的例子,静态工厂本来是一个更好的选择.考虑`StringBuilder.startingWith("prefix")`或`StringBuilder.withInitialCapacity(64)`.这些比`new StringBuilder("prefix")`或`new StringBuilder(64)`更加清晰. (4认同)

sta*_*ker 8

如果您的类具有状态(即使是单个实例;单例模式),也始终使用构造函数.

仅对java.lang.Math中的实用程序方法使用static

例:

public static int max(int a, int b) {
    return (a >= b) ? a : b;
}
Run Code Online (Sandbox Code Playgroud)

不更改对象的任何状态(实例变量),因此可以将其声明为static.