tags:

views:

99

answers:

6

Lets say you have a class SomeClass which has its own implementation of toString(), and also has the ability to parse a new instance of itself by reading that same string.

Which of these methods do you prefer, or find better to use? You can either define it as another constructor:

public SomeClass(String serializedString);

or you can define it as a static method, which in turn creates a new instance (by one of the other constructors, does some with it, and returns the new instance:

public static SomeClass toObject(String serializedString);

Does it even matter? (my hunch is there is no case this matters, but I am trying to make sure)

+5  A: 

My own preference is to keep the parsing logic out of the constructor. That way it can call the appropriate constructors (possibly private) as necessary. It doesn't have to depend on default object construction and so on. So I would go with the toSomeClass() method.

Also, it is not immediately clear that SomeClass(String) will parse an object based on the serialization string. There may be many other meanings to a constructor which takes a String. The toSomeClass() static method makes this clear.

Avi
Didn't want to bias the question, but I totally agree with the points you made
Yuval A
+1  A: 

The static method has the advantage that you can then use the string-reading constructor for something else. Also in general it's better to use static factories than constructors in any nontrivial classes. It gives you more flexibility.

Joonas Pulakka
A: 

To keep some specific logic (like parsing from string) out of constructor is good design policy.

Constructor job is mainly object creation. Initialization and creation of it's fields.

Serialization logic need to be separated from creation. Firstly you may wan't to create separate static method, secondly in evolution of your class you may want to implement some kind of Serializable interface and delegate reading/writing job to another class.

begray
+3  A: 

I agree with Avi's recommendation. I'd like to add two more advantages:

  • A static factory method allows you to return null, which a constructor can't.
  • A static factory method allows you to return a subclass of its defined return type, which can help provide forward compatibility.

One exception: if you're writing a simple value type and using the immutable pattern, I see no reason to use a static factory method.

Barend
A: 

Another advantage to a static constructor is that you can give it a meaningful name. In this case, I would suggest parse:

SomeClass inst = SomeClass.parse("wibble");
oxbow_lakes
+1  A: 

A Java convention for such static methods is:

public class Foo {
    // ...
    public Foo parseFoo (String s) {...}
    // ...
}

as in the standard parseInt(...), parseLong(...), parseDouble(...), etc. Unfortunately, Sun also gave us a different convention with the wrapper classes, as in Boolean.valueOf(...). However, I'd pick one of those conventions and follow it consistently.

joel.neely