19

When should I use a constructor and when should I use static method?

Can you explain above with small snippet? I skimmed through a few threads but I'm still not clear with this.

4
  • 1
    Please read the FAQ, about which questions should be posted here: stackoverflow.com/faq I guess, that this fits to programmers.stackexchange.com Commented Dec 10, 2012 at 14:38
  • 1
    Please read basic java concepts, it would help you in this Commented Dec 10, 2012 at 14:39
  • 1
    Don't ask for small snippets. You have no other choice but read "Effective Java" by Joshua Bloch, Item 1 "Consider static factory methods instead of constructors". It's a must read book for a Java developer Commented Dec 10, 2012 at 14:53
  • 1
    How did this question get 10 upvotes the way it's phrased!? Commented Dec 11, 2012 at 1:49

9 Answers 9

23

Joshua Bloch advises to favor static factory methods instead of constructors (which I think is a good practice). Couple of advantages and disadvantages :

Advantages of static factory methods :

  • unlike constructors, they have names
  • unlike constructors, they are not required to create a new object each time they're invoked (you can cache instances : e.g. Boolean.valueOf(..)
  • unlike constructors, they can return an object of any subtype of their return type (great flexibility)

Disadvantages of static factory methods :

  • They are not really distiguishable from other static methods (it's hard to find out how to initialize an object if you are not familiar with the API)
  • The main disadvantage (if you use only static factory methods, and make constructors private) is that you cannot subclass that class.
Sign up to request clarification or add additional context in comments.

Comments

20

Use a public constructor when you only ever want to return a new object that type and you want simplicity.

A good example is StringBuilder as it's mutable and you are likely to want a new object each time.

public String toString() {
    StringBuilder sb = new StringBuilder();
    // append fields to the sb
    return sb.toString();
}

Use a static factor method when you might want to re-use objects (esp if immutable), you might want to return a sub-class or you want descriptice construction. A good example is EnumSet which has a number of static factories which do different things even though some have the same arguments.

EnumSet.noneOf(RetentionPolicy.class);
// has the same arguments, but is not the same as
EnumSet.allOf(RetentionPolicy.class);

In this case, using a static factory makes it clear what the difference between these two ways of construction the set.

Also EnumSet can return two different implementations, one optimised for enums with a small number of values (<= 64) RegularEnumSet and another for many values called JumboEnumSet

6 Comments

can you give any real time scenario based example
I'd actually claim that StringBuilder is a good example of case where a static factory would have been a better choice. Consider StringBuilder.startingWith("prefix"), or StringBuilder.withInitialCapacity(64). These are more immediately clear than new StringBuilder("prefix") or new StringBuilder(64).
@Peter Lawrey: Small code snippet with comments would have been better.
@JoeKearney While I agree it's slightly clearer, for some increase in complexity, I suspect the only time you are likely to get confused is new StringBuilder('A'); ;)
@PeterLawrey I think that deliberately misses the point. StringBuilder is a fairly common class, so you know what each constructor does. But assume you are using a new library and you are faced with these cctors: new MyThing(32), new MyThing("New Object"), and new MyThing(). What does each of these do? Static methods can have descriptive and unambiguous names, and they allow you to use the same parameter list for different purposes MyThing.WithSize(8) and MyThing.WithContent(8), which would not be possible with constructors.
|
8

Always use a constructor if your class has a state (even for a single instance; singleton pattern ).

Only use static for utility methods like in java.lang.Math

Example:

public static int max(int a, int b) {
    return (a >= b) ? a : b;
}

Doesn't change any state (instance variables) of an object, thus it can be declared static.

2 Comments

is this right? Assuming we're not using enums, doesn't the singleton pattern rely on a static "factory" method?
@bharal Good point, a singleton usually has a private constructor, and a static factory method.
4
  1. Use constructor when you need an object and other stuffs like functions and variables having one copy for every object.
  2. when you want to do something without creating object then use static method.

    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());
    }
    }
    

Comments

3

Static factory methods have names, constructors don't. Thus factory methods can carry natural documentation about what they do that constructors can't. For example, see the factory methods in the Guava Libraries, like ImmutableMap.copyOf(otherMap). While this might have little effect on behaviour of construction, it has a huge effect on readability of the code. Definitely consider this if you're publishing an API.

Also you can use a factory when you need to do any more complicated configuration of the object you're creating, especially if you need to publish to other threads (registering in pools, exposing as an MBean, all manner of other things...) to avoid racy publication. (See e.g. Java Concurrency In Practice section 3.2)

Static methods that do something (e.g. Math.min) are not really the same thing as static factories, which can be considered direct replacements for constructors, with added flexibility, evolvability and (often) clarity.

Comments

2

Whenever you need to create an instance of an object you will have to use the constructor.

So, if you want to create a Car object, then you will need a constructor for that.

The keyword static means, that your method can be called without creating an instance.

4 Comments

yeah exactly ,but can you give any scenario when to use what ??
For instance if you want to use a singleton, which means that you have only one instance of the object, which might be shared with others, then you need a static method, which will internally will call the constructor. So, every time someone wants an instance of that object you will return always the same, thus you will consume memory only for one.
@ipinak:Can you give me a small snippet which explains above car eg ?
@ipinak:Code example with comments mentioning each line would be great. Thanks for answering.
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]";
   }
}

In general you will use static class with data that are not correlated with the instance of the object.

Another example is:

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.
   }
}

As the posts above say, it's just a matter of what you want to do and how you want to do it. Also, don't try to understand everything rightaway, write some code then try different approaches of that code and try to understand what your code does. Examples are good, but you need to write and then understand what you did. I think it's the only way you will figure out why you do staff the way you have to do.

Comments

1

Static methods do not have to instantiate new objects everytime. Since object instantiation is expensive it allows instances to be cached within the object. So, it can improve performance.

This is the explanation from the Effective Java :

This allows immutable classes (Item 15) to use preconstructed instances, or to cache instances as they’re constructed, and dispense them repeatedly to avoid creating unnecessary duplicate objects. The Boolean.valueOf(boolean) method illustrates this technique: it never creates an object. This technique is similar to the Flyweight pattern [Gamma95, p. 195]. It can greatly improve performance if equivalent objects are requested often, especially if they are expensive to create.

Comments

1

i.e. if you want to use a singleton, which means that you have only one instance of the object, which might be shared with others, then you need a static method, which will internally will call the constructor. So, every time someone wants an instance of that object you will return always the same, thus you will consume memory only for one. You always need a constructor in object oriented programming, in every OO language. In java an in many other languages the default constructor of an object is implied, and built automatically. But you need some custom functionality you have to make your own.

Above you see a few good examples of the usage. However, if you have something specific in your mind, please let us know. I mean if you have a specific case where you are not sure if you should use a static method or a constructor. Anyhow, you will definitely need a constructor, but I am not sure about the static method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.