我何时应该使用构造函数,何时应该使用静态方法?
你能用小片段解释一下吗?我浏览了几个线程,但我仍然不清楚这一点。
答案 0 :(得分:19)
当您只想要返回一个类型的新对象并且想要简单时,请使用公共构造函数。
一个很好的例子是StringBuilder,因为它是可变的,你可能每次都想要一个新对象。
public String toString() {
StringBuilder sb = new StringBuilder();
// append fields to the sb
return sb.toString();
}
当您可能想要重用对象时使用静态因子方法(特别是如果不可变),您可能想要返回子类或者您想要构造构造。一个很好的例子是EnumSet,它有许多静态工厂,即使有些工具具有相同的参数,它们也会做不同的事情。
EnumSet.noneOf(RetentionPolicy.class);
// has the same arguments, but is not the same as
EnumSet.allOf(RetentionPolicy.class);
在这种情况下,使用静态工厂可以清楚地了解这两种构造方法之间的区别。
此外,EnumSet可以返回两个不同的实现,一个针对具有少量值(< = 64)RegularEnumSet
的枚举进行优化,另一个针对称为JumboEnumSet
答案 1 :(得分:19)
Joshua Bloch 建议使用静态工厂方法而不是构造函数(我认为这是一种很好的做法)。优点和缺点:
静态工厂方法的优点:
Boolean.valueOf(..)
缺点:
答案 2 :(得分:8)
如果您的类具有状态(即使是单个实例;单例模式),也始终使用构造函数。
仅对java.lang.Math中的实用程序方法使用static
示例:
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
不会更改对象的任何状态(实例变量),因此可以将其声明为静态。
答案 3 :(得分:3)
静态工厂方法有名称,构造函数没有。因此,工厂方法可以携带有关构造者不能做的事情的自然文档。例如,请参阅Guava Libraries中的工厂方法,如ImmutableMap.copyOf(otherMap)
。虽然这可能对构造行为几乎没有影响,但它对代码的可读性有很大影响。如果您要发布API,请务必考虑这一点。
当您需要对正在创建的对象进行更复杂的配置时,也可以使用工厂,特别是如果您需要发布到其他线程(在池中注册,作为MBean公开,各种其他方式) ...)以避免出版。 (参见例如Java Concurrency In Practice部分3.2)
做某些东西的静态方法(例如Math.min
)与静态工厂不同,静态工厂可以被视为构造函数的直接替换,具有更大的灵活性,可进化性和(通常)清晰度。
答案 4 :(得分:3)
如果您想在不创建对象的情况下执行某些操作,请使用静态方法。
Example:
public class Test {
public int value;
public static int staticValue;
public int getValue() {
return ++value;
}
public static int getStaticValue() {
return ++staticValue;
}
}
public class TestClass {
public static void main(String[] args) {
Test obj = new Test();
Test obj1 = new Test();
S.o.p(obj.getValue());
S.o.p(obj1.getValue));
S.o.p(Test.getStaticValue());
S.o.p(Test.getStaticValue());
}
}
答案 5 :(得分:2)
每当您需要创建对象的实例时,您将不得不使用构造函数。
所以,如果你想创建一个Car对象,那么你需要一个构造函数。
关键字static表示可以在不创建实例的情况下调用您的方法。
答案 6 :(得分:2)
class Car
{
private int num_of_seats;
public Car(int number_of_seats)
{
this.num_of_seats = number_of_seats;
}
// You want to get the name of the class that has to do with
// this class, but it's not bounded with any data of the class
// itself. So you don't need any instance of the class, and
// you can declare it as static.
static String getClassName()
{
return "[Car]";
}
}
通常,您将使用静态类,其数据与对象的实例无关。
另一个例子是:
class Ring
{
private List nodes;
public Ring(List nodes)
{
this.nodes = nodes;
}
// You want to calculate the distance of two ids on the ring, but
// you don't care about the ring. You care only about the ids.
// However, this functionality logical falls into the notion of
// the ring, that's why you put it here and you can declare it
// as static. That way you don't have to manage the instance of
// ring.
static double calculateDistance(int id_1, int id_2)
{
return (id_1 - id_2)/383; // The divisor is just random just like the calculation.
}
}
正如上面的帖子所说,这只是你想做什么以及你想怎么做的问题。此外,不要试图立即理解所有内容,编写一些代码然后尝试不同的代码方法并尝试理解代码的作用。示例很好,但您需要编写然后了解您所做的事情。我认为这是你弄明白的唯一方法 为什么你按照自己的方式做员工。
答案 7 :(得分:1)
静态方法不必每次都实例化新对象。由于对象实例化很昂贵,因此允许将实例缓存在对象中。因此,它可以提高性能。
的解释这允许不可变类(第15项)使用预构造 实例,或者在实例构建和缓存实例时进行缓存 他们反复避免创建不必要的重复对象。该 Boolean.valueOf(boolean)方法说明了这种技术:它永远不会 创建一个对象。这种技术类似于Flyweight模式 [Gamma95,p。 195]。如果等效,它可以大大提高性能 经常要求对象,特别是如果它们很昂贵的话 创建
答案 8 :(得分:1)
即。如果你想使用单例,这意味着你只有一个对象的实例,可能与其他人共享,那么你需要一个静态方法,它将在内部调用构造函数。因此,每当有人想要该对象的实例时,您将始终返回相同的内容,因此您将仅消耗一个内存。在每种OO语言中,总是需要面向对象编程的构造函数。在java和许多其他语言中,隐含了一个对象的默认构造函数,并自动构建。但是你需要一些自定义功能来制作自己的功能。
上面你会看到一些很好的用法示例。但是,如果您有特定的想法,请告诉我们。我的意思是,如果你有一个特定的情况,你不确定是否应该使用静态方法或构造函数。无论如何,你肯定需要一个构造函数,但我不确定静态方法。