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.
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.
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
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.
Use constructor when you need an object and other stuffs like functions and variables having one copy for every object.
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());
}
}
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.
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.
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.
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.
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.
Related
Imagine any Java class which is entirely immutable. I will use the following as an example:
public class Point2D {
public final int x;
public final int y;
public Point2D(final int x, final int y) {
this.x = x;
this.y = y;
}
}
Now consider adding an operator on this class: a method which takes one or more instances of Point2D, and returns a new Point2D.
There are two possibilities for this - a static method, or an instance method:
public static Point2D add(final Point2D first, final Point2D second) {
return new Point2D(first.x + second.x, first.y + second.y);
}
or
public Point2D add(final Point2D other) {
return new Point2D(this.x + other.x, this.y + other.y);
}
Is there any reason to pick one over the other? Is there any difference at all between the two? As far as I can tell their behaviour is identical, so any differences must be either in their efficiency, or how easy they are to work with as a programmer.
Using a static method prevents two things:
mocking the class with most mocking frameworks
overwriting the method in a subclass
Depending on context, these things can be okay, but they can also create serious grief in the long run.
Thus, me personally, I only use static when there are really good reasons to do so.
Nonetheless, given the specific Point2D class from the question, I would tend to actually use the static methods. This class smells like it should have "value" semantics, so that two points for the same coordinates are equal and have the same hash code. I also don't see how you would meaningfully extend this class.
Imagine for example a Matrix2D class. There it might make a lot of sense to consider subclasses, such as SparseMatrix for example. And then, most likely, you would want to override computation intensive methods!
There is no practical difference between the two. Where it matters most is in the area of OO design and readability.
The static version of the operation seems more aligned with the static factory pattern. In addition to using a common design pattern, it is a clear creational design, which seems to meet its intent: to create a new object.
On the other hand, instance methods creating new objects are very practical when it comes to immutable objects. The best example of this is the String methods (String.concat(string), etc.). In my opinion, this is more a question of practicality (you don't want to mutate the state of the object; you need to augment the it, but the operation has to result in a new instance).
Is there any reason to pick one over the other?
There may be cases where one fits better than the other (for example, I'd prefer the static method to the instance version in a stream pipeline's reduction - as an example), but there is no evident, absolute preference to be claimed here. So...
I would use the static method for factory operations (although I'd call the method something more like create..., newInstance... for clarity)
I would use the instance method for transformations operations that return new instances to avoid mutating the object.
First and foremost, if it is an immutable make it unsubclassable to others. Usually final is used although you can hide the constructor. Not particularly relevant in this case, but static creation methods allows common values to be reuse instances, specialist implementations to be selected and the ugly diamond (<>) notation to be elided. (If you call your static creation method of it is clear to use when qualified with the type name.)
Addition is usually written as infix. If there are subexpressions involved this will make the client code look much better, though the Java syntax will still force you to have parentheses everywhere. A static method requires qualification or an import static for the client (the latter not really helpful if the method has a name like and, and 'import *' is bad if there other static method that don't make sense without qualification).
Reserve static methods for cases where the object is, in a sense, incidental to the function. For example String's join and format.
As for testing, it should not be necessary to mock a value class or static method. Immutable types should have trusted implementations and therefore not be subtypable by others.
Java lacks the ability to specify interfaces for static methods. A method in an interface must be non static. This makes it impossible to specify requirements for Classes. Instead one is limited to specify requirements for Objects. This makes it also impossible for example to specify the singleton functionality in an interface, because in Java the singleton pattern requires to be implemented as a static method. Here is a nice article, which explains it, but it is only in German.
When one is forced to implement something as a functionality of an object instead of the functionality of a class, an instance of this object has to be created, before the functionality can be used. But such object has some special characteristic: it has no state, because class functionality has no state either. Theoretically the instance creation of an object without data can be optimized to an NOP, because all methods can be linked to the class instead of any object. Java could implement some kind of implicit singleton functionality.
But how it this actually handled?
Think about some kind of functionality without any state.
interface Adder<T> { T add(T ... arguments); }
Basically it would be sufficient to implement this as a static method:
class IntegerAdder implements Adder<Integer> {
public static Integer add (Integer ... arguments) { }
}
But because Java does not allow static interface methods it has to be implemented in a non static way. The result is, that when ever an IntegerAdder is required one has to create an instance.
IntegerAdder integer_adder = new IntegerAdder();
Integer a = 1;
Integer b = 2;
Integer c = integer_adder.add (1, 2);
I fear this might be slower than the version without the instance creation:
Integer a = 1;
Integer b = 2;
Integer c = IntegerAdder.add (1, 2);
But how much slower is it in reality? Is it possible for the Java compiler to optimize the first version in that way that it performs as fast as the second one? And is this actually done?
You can create an instance of IntegerAdder once and reuse it, it is thread safe. Also pay attention that Integer ... arguments leads to 1) using objects instead of primitive ints 2) creating an array to pass parameters. Both things should be avoided if performance is concern
So I'm learning java. I'm one month in and I just learned about constructors. But I don't see the whole purpose of creating one. Why and when would I ever want to use one? I get the whole idea that it does not have a main method and you can call a constructor from your main class. Anyone can enlighten me on this topic, it would help me a great deal.
Constructors are what you use to initialize/set up the instances of your classes.
If you have an object that needs some processing before it is usable (initializing members for instance), you should do that in the constructor.
Ideally, you should never have "partially built" objects (i.e. objects that are "live", that you hold a reference to, but that are not yet usable). Without constructors, you'd be permanently creating partially built objects, and that is very error-prone. (Theory and practice don't always match, but keep that idea in mind.)
You use a constructor to create new objects. Yes, you can write Java just using static methods - but then you're really not writing object-oriented code, and you'll have a hard time using much of the standard library, either.
Most of your time you should be working with and thinking in terms of objects - and they need to be constructed before they can be used... and that's where constructors come in. They create an object, often with parameters specifying the initial state or other important information about the object.
To be honest, it's probably not worth worrying about them just yet, if you don't see the point yet. It's likely that as you learn more, you'll naturally start using objects more (maybe collections to start with, for example) and you'll get the hang of it. Rest assured, it is important to have constructors in Java, but I'm sure you'll understand why in the course of time. (Of course, if this answer has helped you to appreciate their value already, I'm glad - but if not, don't worry :)
It might seem as if you're having trouble understanding the basic concepts of objects and object-oriented programming. An explanation by example; This class represents a type of thing, namely a car:
public class Car{
// Licence plate number. This is private, so it can
// not be accessed directly from outside the class.
private String hiddenRegNr = "";
private static String description = "This is a car".
// The constructor, which sets the value of hiddenRegNr
public Car(String regNr){
hiddenRegNr = regNr;
}
// Method for reading hiddenRegNr, the only
// way to access it after instantiation.
public String getRegNr(){
return hiddenRegNr;
}
// A static method. Can be used withouth instantiation.
public static String getDesc(){
return description;
}
}
From some other class, you could call this class, and make instances of it; actual representations of different cars. They represent different cars, but are based on the same "model", i.e., the class Car.
Car myFirstCar = new Car("SR12345");
Car myOtherCar = new Car("XZ54321");
Now you have two different cars, with two different registration numbers. These are independent instances of the type car. They exist in memory, and may contain different values (in this case, different registration numbers).
myFirstCar.getRegNr(); // Will return SR12345
mySecondCar.getRegNr(); // will return xz54321
The first thing to notice here, is that you can only specify the registration number once per car, namely upon creation. That is the point of the constructor: It sets values, and does other stuff that needs to be done when objects (instances) are created.
Now, note the difference between getRegNr() and getDesc(): The keyword "Static" means that the second method is related directly to the class, and not to each instance. This means that:
Calls to getDesc() is made on the class, not an instance:
Car.getDesc();
Calls to getDesc() will return the same value for all instances of the class car
The variable description (which is also static) will be the same for all instances of Car
The static method getDesc() CAN NOT access the variable hiddenRegNr, since that variable is related to a specific instance. Trying to refer to a variable in an instance from a static context (such as getDesc()) will cause an exception to be thrown. You might say that hiddenRegNr will not have been set when you call
Car.getDesc();
because the constructor was never called, so it was never given any value.
Constructors are used to initialize a class and give parameters to a class. What is important is that they let you set the class state on creation. This allows you to use specific instances of a class with different data field values instead of relying on purely static information. Take the following example:
class Obj {
private int state = 0;
public Obj(int state) {
this.state = state;
}
public Obj() {
state = 1;
}
}
Now in main (or wherever) you can have:
Obj obj1 = new Obj();
Obj obj2 = new Obj(2);
The two objects have different states (one is at state 1, the other is at state 2). If you were relying on static methods and members, the objects would share one state and would not be independent of each other.
It is also important to note that constructors (specifically the new keyword) allocate memory for a given object internally so you don't have to worry about using malloc and other memory management. So they are important in that sense as well.
It is used to create objects. Objects are the main concept in OOP, so creating them is an important step. The main class method is just an entry point to your program. If you don't create objects your program will be procedural rather than object-oriented. This is why to use a constructor.
And why to create a constructor - sometimes you need to construct an object with some required parameters. There is also a default no-argument constructor, but if you want to initialize your object with additional arguments - you create a constructor taking those arguments.
Actually constructor is needed IF you need to assign unique initial state to an instance of a class. In Java i only just realized (by a friend) that we can do this:
public class MyClass1 {
private class MyClass2 {}
private MyClass2 myobj2 = new MyClass2();
}
So no need for implicit constructor.
But if something like follows, you need constructor.
public class MyClass1 {
private class MyClass2 {
private int id_ = 0;
public MyClass2(int id) { id_ = id; } // how to reach this?
}
private MyClass2 myobj2 = new MyClass2(1); // (this doesn't work. Not unique)
public MyClass1(int id) { myobj2 = new MyClass2(id); } // by this!
}
MyClass1 obj1 = new MyClass1(100);
MyClass1 obj2 = new MyClass1(200);
I will give you an example, imagine you have a car class.. when you call the constructor of the car class you have an car object. on this car object is possible to use diffent methods. And you could create as many as car objects as you want.
in this site it says that a new object isnt being created each time , which leads to efficiency, but by what i can see an object is being created each time in the static method..
do not need to create a new object
upon each invocation - objects can be
cached and reused, if necessary.
http://www.javapractices.com/topic/TopicAction.do?Id=21
so why are the static factory methods are so efficient?
isnt writing something like this : Object obj=new Object is same as if i did Object obj=Someclass.GetObj();
class Someclass
{
public static Object GetObj()
{
return new Object
}
}
There is caching, but a new object is created either way...
Objects can be cached and reused. They aren't always. There are a number of other advantages, like:
better naming of the method
returning subclasses
There is an item in Effective Java for that, so go ahead and read it. The book is a must-read anyway.
Update: as I said, object can be cached. But it depends on the implementation. The one you show does not cache them. The one shown by Peter caches them. You have that option. With a constructor - you don't.
They are more flexible - for example if the input parameters for new object are not valid, you can return null or some null object implementation (=instance, which does nothing, but will not break your code by NullPointerException), or, as previously mentioned by others, you can cache created instances. There is another benefit from using factory methods over constructors - you can name them whatever you like, which can be more readable, if there are multiple constructors with lots of optional parameters.
EDIT: if you want to use only one instance, you can use this simple factory:
class Someclass{
private static Object o=new Object();
public static Object getObj(){
return o;
}
}
When you use new Object(), a new Object has to be created.
If you use a static factory, it can optionally create a new object, or it can reuse an existing one.
A simple example is using Integer.valueOf(int) instead of new Integer(int). The static factory has a cache of small integers and can save to the creation of a significant portion of integers. For some use cases this can be all the integers used. The later case will always create a new object which is relatively inefficient.
The link you presented provides very different explanation of a Factory Pattern. Generally factory pattern is used to obtain instances of classes whcih implement same interface but provide different behavior for the same contract. It allows us to choose different implementation at run time. Check out the example here:
http://www.allapplabs.com/java_design_patterns/factory_pattern.htm
Factory pattern is not generally used for caching objects. Singleton pattern is defined to ensure only one instance of the object is created.
The idea is that you use them as a strategy. If later you want to implement caching, you just change that method and add it in there. Compare this with having "new Bla()" scattered all over the code, and trying to implement caching for the Bla class.
Since the method is static, and usually just a few lines of code, it means it can be resolved at compile time, and even inlined.
Thus there is no advantage of using "new Bla()" instead of factory methods at all.
Using factory in some situations you could make your code more flexible, faster and also better readable.
For example, imagine, you have to write class which download some data from url
public class WavAudio {
private byte[] raw;
private static HashMap<String,WavAudio> cache;
private WavAudio(byte[] raw){
this.raw=raw;
}
public static loadFromUrl(String someUrl){
//If data has been loaded previously we don't have to do this more (faster..)
if (cache.containsKey(someUrl))
return cache.get(someUrl);
//Else we'll load data (that would take some time)
InputStream ires=(new URL(someUrl)).openStream();
ByteArrayOutputStream baos=new ByteArrayOutputStream();
byte[] raw = new byte[4096];
int nBytesRead;
while ((nBytesRead = ires.read(raw, 0, raw.length))>0)
baos.write(raw, 0, raw);
byte[] downloaded=baos.toByteArray();
WavAudio curr=new WavAudio(raw);
cache.put(someUrl,raw);
return raw;
}
public static void main(String[] args){
WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1");
SomePlayer.play(wav); //the first melody is playing
WavAudio wav=WavAudio.loadFromUrl("http://someUrl_2");
SomePlayer.play(wav); //the second melody is playing
//won't be downloaded twice
WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1");
SomePlayer.play(wav);
}
}
First of all please forgive me if its a really dumb question, I am just trying to learn this language to its core. I am reading Effective Java and the very first chapter talks about Static factory methods vs. Constructors. Their pros and cons. Few things that are confusing to me are:
class of an object returned by static factory method is nonpublic - what exactly does it mean?
unlike constructors static factory methods are not required to create a new object each time they are invoked - How does this happen? I am invoking factory method only to obtain a new object and do we put a check in factory method for checking if object already exists?
Thanks.
class of an object returned by static factory method is nonpublic -
what exactly does it mean?
It means that the actual class of the objects returned by a static factory method can be a subclass of the declared type, and this subclass does not have to be public. It's just another implementation detail that client code should not care about.
unlike constructors static factory methods are not required to create a new object each > time they are invoked - How does this happen? I am invoking factory method only to obtain a new object and do we put a check in factory method for checking if object already exists?
Yes, that's one way this could be done. But really, anything is possible.
First off, kudos to you for your choice in Java-lit: Bloch's book is an excellent primer.
To answer your 2nd question ('unlike constructors static factory methods are not required to create a new object each time they are invoked'), it's important to realize that what Bloch is saying here is that with a static factory you have the option of either: returning a new object or returning a pre-existing one. It all depends on what you want to do.
For example, let's suppose you have a really simple value class of type Money. Your static factory method probably should return a new instance -- that is, a new object with a specific value for Money. So, like this:
public class Money {
private Money(String amount) { ... } /* Note the 'private'-constructor */
public static Money newInstance(String amount) {
return new Money(amount);
}
}
But let's say you have some object that manages some resource and you want to synchronize access to that resource through some ResourceManager class. In that case you probably want your static factory method to return the same instance of itself to everyone -- forcing everyone to go through that same instance, so that that 1 instance can control the process. This follows the singleton-pattern. Something like this:
public ResourceManager {
private final static ResourceManager me = new ResourceManager();
private ResourceManager() { ... } /* Note the 'private'-constructor */
public static ResourceManager getSingleton() {
return ResourceManager.me;
}
}
The above method forces your user to only ever be able to use a single instance, allowing you to precisely control who(and when) has access to whatever it is you are managing.
To answer your first question, consider this (admittedly not the best example, it's pretty ad-hoc):
public class Money {
private Money(String amount) { ... }
public static Money getLocalizedMoney( MoneyType localizedMoneyType, String amount ) {
switch( localizedMoneyType ) {
case MoneyType.US:
return new Money_US( amount );
case MoneyType.BR:
return new Money_BR( amount );
default:
return new Money_US( amount );
}
}
}
public class Money_US extends Money { ... }
public class Money_BR extends Money { ... }
Note how I can now do this:
Money money = Money.getLocalizedMoney( user_selected_money_type );
saveLocalizedMoney( money );
Again, a really contrived-example but hopefully it helps you see more or less what Bloch was getting at with that point.
The other answers were good -- I just think that, as a beginner, sometimes it helps to see some actual code.
When you use the new keyword then you as the developer know that the JDK will create a new instace of that object. What the author is saying, when you use a static method, the developer no longer knows if the method is creating a new instance or possibly doing something else. Something else can be, reusing cached data, object pooling, creating a private implementation and returning a subclass of the class.
class of an object returned by static factory method is nonpublic
Frequently a static factory method will return either an an object typed as an interface (most common), or sometimes some base class (less common). In either case, you don't know the exact class of the returned object.
The advantage of this is getting an object whose behaviour you know without worrying about the messy details of what class it instantiates.
unlike constructors static factory methods are not required to create a new object each time they are invoked
To understand this, consider the case of working with a singleton. You may call .getInstance() on some factory classes to get the singleton instance of an certain object. Typically, what this does is create an instance of the object if it doesn't already exist, or give you the existing instance if it already does. In either case, you get back a copy of the object. But you don't (and won't) know if this singleton had to be created, or if one had already been constructed previously.
The advantage of this is that the lifecycle of the object and when it is created is managed for you.
Both of your questions can be answered by looking at some code that makes use of both of these properties of static factory methods. I suggest looking at Guava's ImmutableList.
Note how the no-arg factory method of() always returns the same instance (it doesn't create a new instance each time). If you look carefully, you'll also notice that its copyOf(Iterable) factory method actually returns the object that is passed to it if that object is itself an ImmutableList. Both of these are taking advantage of the fact that an ImmutableList is guaranteed to never change.
Notice also how various factory methods in it return different subclasses, such as EmptyImmutableList, SingletonImmutableList and RegularImmutableList, without exposing the types of those objects. The method signatures just show that they return ImmutableList, and all subclasses of ImmutableList have package-private (default) visibility, making them invisible to library users. This gives all the advantages of multiple implementation classes without adding any complexity from the user's perspective, since they are only allowed to view ImmutableList as a single type.
In addition to ImmutableList, most instantiable classes in Guava utilize static factory methods. Guava also exemplifies a lot of the principles set forth in Effective Java (not surprising, given that it was designed by those principles and with guidance from Josh Bloch himself), so you may find it useful to take a look at it more as you're working through the book.