假设您有一个类SomeClass
,它有自己的toString()
实现,并且还能够通过读取相同的字符串来解析自己的新实例。
您更喜欢哪种方法,还是更好用? 您可以将其定义为另一个构造函数:
public SomeClass(String serializedString);
或者您可以将其定义为静态方法,该方法又创建一个新实例(由其他构造函数之一,用它做一些,并返回新实例:
public static SomeClass toObject(String serializedString);
甚至重要吗? (我的预感是没有任何重要的事情,但我正在努力确保)
答案 0 :(得分:5)
我自己的偏好是将解析逻辑保留在构造函数之外。这样它就可以根据需要调用适当的构造函数(可能是私有的)。它不必依赖于默认对象构造等。所以我会使用toSomeClass()方法。
此外,SomeClass(String)不会立即清楚基于序列化字符串解析对象。对于采用String的构造函数,可能还有许多其他含义。 toSomeClass()静态方法明确了这一点。
答案 1 :(得分:3)
我同意Avi的建议。我想补充两个优点:
一个例外:如果您正在编写一个简单的值类型并使用不可变模式,我认为没有理由使用静态工厂方法。
答案 2 :(得分:1)
静态方法的优点是,您可以将字符串读取构造函数用于其他内容。通常,在任何非平凡的类中使用静态工厂比构造函数更好。它为您提供了更大的灵活性。
答案 3 :(得分:1)
此类静态方法的Java约定是:
public class Foo {
// ...
public Foo parseFoo (String s) {...}
// ...
}
与标准parseInt(
... )
,parseLong(
... )
,parseDouble(
... )
等一样不幸的是,Sun还给了我们与包装类的不同的约定,如Boolean.valueOf(
... )
。但是,我会选择其中一个约定并一致地遵循它。
答案 4 :(得分:0)
从构造函数中保留一些特定的逻辑(比如从字符串解析)是一个很好的设计策略。
构造函数作业主要是对象创建。初始化和创建它的字段。
序列化逻辑需要与创建分开。首先,您可能不想创建单独的静态方法,其次在类的演化中,您可能希望实现某种Serializable接口并将读/写作业委托给另一个类。
答案 5 :(得分:0)
静态构造函数的另一个优点是可以为其指定有意义的名称。在这种情况下,我建议parse
:
SomeClass inst = SomeClass.parse("wibble");