The motivation for using Static Factory methods staes as:
The most obvious motivation for Replace Constructor with Factory
Method comes with replacing a type code with subclassing.
You have an object that often is created with a type code but now
needs subclasses. The exact subclass is based on the type code.
However, constructors can only return an instance of the object that
is asked for. So you need to replace the constructor with a factory
method.
Can anyone please explain this with code? And what does this type code mean?
A second advantage that a factory method has over a bare constructor is that it can return an existing object. The Integer.valueOf(int) method makes good use of this. By contrast, new always creates a new object.
Finally, if we broaden the discussion slightly, a non-static factory method (e.g. in the form of a factory object) allow you use polymorphism to implement different object creation strategies.
And what does this type code mean?
You need to read this in the context of the page that you got this from. What the page is talking about is a single class that represents different "types" of thing. (In the example given, it is different types of employee represented by one Employee class.) The "type code" is simply the attribute of the class that discriminates the different types.
Imagine we have a Person class with a field called type to indicate if that person is a teacher or a student. This will be the type code.
Now imagine we replace this type field with an object hierarchy: Person class with 2 subclasses Teacher and Student.
If I use the constructors then I can only create a specific type of person i.e. new Teacher() or new Student()
but if I want a method that creates a different kind of person based on some logic then I can do:
public static Person newPerson() {
// can return either a Teacher or a Student
}
A constructor can only return one implementation, however a static factory method can return any number of implementations, often a sub-class of the class referred to. Static factory methods also have the advantage of being named so you can have different behaviour for the same arguments.
e.g. These two methods return a sub-class of EnumSet (based on the number of elements in the enum) with different values based on the name (even though the arguements are the same)
EnumSet<MemoryType> memoryTypes = EnumSet.noneOf(MemoryType.class);
EnumSet<MemoryType> memoryTypes2 = EnumSet.allOf(MemoryType.class);
From the source
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
You can see it has one implementation for smaller enum sets and another for larger ones.
Related
This is more of a style question, where I'm unsure what solution to my problem would be the "cleanest".
The implementation details are not important, what I want to do is the following:
I've got an abstract class that is extended by several subclasses which are all very similar in nature. I want to hide these classes from the client by making them instantiable only through a static method in the superclass which returns a superclass reference to a subclass instance (the concrete class is determined by the method parameters).
So far so good, I believe that's a very common thing to do.
Now, these subclasses I'm talking about can be divided into two groups, one group, whose members require two parameters in order to be constructed and another group, whose members need an additional parameter.
So now my question is this: How can I let the client obtain both of these types via a static method like the one mentioned above. Do I provide two static methods with different paramter lists? Do I force the client to pass a zero on the third optional parameter that the first group doesnt need? Is there a design pattern for this? (I have considered the Builder pattern from Effective Java, but as far as I understnad it that ones usually used in a different context). Or do I modify my inheritance hierarchy?
Any answers would be appreciated!
EDIT:
I believe my question is a little bit convoluted at the moment, all add a little bit of code to make it clearer:
abstract class SuperClass{
public static SuperClass getSuperClass(String type, int i1, int i2, int optional) {
/*
*'type' alone determines which concrete subclass is instanciated
*'optional' is only needed for the construction for some of those 'types'
*so the implementation of this method might look like this:
*/
switch(type) {
case "1":
return new Subclass1(i1, i2);
break;
case "2":
return new Subclass2(i1, i2, optional);
break;
/*
*So the problem is this: always passing 'optional' is weird if it
*is then simply discarded in some cases.
*Overloading is weird as well because I don't want to split up
*the switch statement or check for exceptions in every case
*(when optional is/is not declared for types where it
*shouldn't/should be)
*/
}
}
You have two options :
Option 1
Your static factory method in the super class can be implemented using var-args :
public static SuperClass newInstace(int...parameters) {
SuperClass superClass = null;
if(parameters.length == 2) {
if(parameters[1]>=5) {//instantiate a subclass based on a value
super = new SubClass1(parameters[0],parameters[1]);
} else {
super = new SubClass2(parameters[0],parameters[1]);
}
} else if(parameters.length == 3) {
if(parameters[2]>=5) {
super = new SubClass3(parameters[0],parameters[1],parameters[2]);
} else {
super = new SubClass4(parameters[0],parameters[1],parameters[2]);
}
} else {
throw new IllegalArgumentException("Invalid number of parameters passed to newInstance. Expected number of parameters [min = 2, max = 3]")
}
return superClass;
}
Option 2
Alternately, you could overload the newInstance method and have one that takes 2 parameters and the other that takes 3 parameters.
There are pros and cons of both approaches as described below :
When the frequency at which you expect new fields to be introduced in existing subclasses or the frequency at which you expect new subclasses to be introduced with more fields than the existing ones is extremely low, approach 1 is a better option.
When the frequency at which you expect new fields to be introduced in existing subclasses or the frequency at which you expect new subclasses to be introduced with more fields than the existing ones is relatively higher, approach 2 is a better option since approach 1 will result in a very large method body.
You could pass a configuration strings, or configuration object (e.g. Properties) which has as much detail as the implementation needs. It could be 1 or 100 arguments. However, for the caller there is one and only wrapping argument passed.
It depends. It sounds like that your superclass static method returns a SuperClass instance. If so, you can return different subclass instances according to the additional parameter.
Consider an abstract class Vehicle. Now two abstract classes SingleDeckVehicle and MultiDeckVehicle extend Vehicle and let the first two parameters be the number of wheels and the number of seats, and the additional parameter be the number of decks of the vehicle. Then, the number of deck will be important and indeed your client will pass a 1 as the third argument if he/she wants a SingleDeckVehicle instance.
However, you can also create another static method. Suppose you have defined a static method Vehicle.getVehicle(int wheelNo, int seatNo, int deckNo). You may also define another: Vehicle.getSingleDeckVehicle(int wheelNo, int seatNo) which returns Vehicle.getVehicle(wheelNo, seatNo, 1);.
A similar example is BorderFactory:
http://docs.oracle.com/javase/7/docs/api/javax/swing/BorderFactory.html. I hope I understood your question correctly...
I am using a vector to store objects of AnAbstractClass superclass. The abstract class contains only two non-constructor methods:
public final String getName() {
return name;
}
public abstract int getCost();
Within each subclass I created a getCost method. Within anotherClass I have the vector of abstract class objects. In a method of anotherClass I am using a string that contains name, cost, and other data types that are specific to each of the multiple subclasses. I am currently accessing the vector to retrieve name and cost just fine.
However, when I try to access the other fields (ie: getColor or getSize that are specific to each subclass I run into the following compile error:
Error: cannot find symbol
symbol: method <mySubClassMethod>()
location: class <MyAbstractClass>
How can I efficiently design a solution to this dilemma?
To access methods specific to a subclass you need to cast to the subclass.
Example:
Subclass foo = (Subclass) myAnAbstractClassInstance;
If you don't know what subclass you have, you can do a type check using instanceof
Example
// Subclass implements size and color, but superclass does not
if (foo instanceof Subclass) {
Subclass foobar = (Subclass) foo;
int size = foobar.size();
String color = foobar.color();
}
Alternative solutions:
1. Make all subclasses provide all methods (even if they do nothing)
2. Make all subclasses provide a method that lets you know what methods they support
Either add getColor and getSize to the abstract class, or if you want something totally dynamic, try having a method like getData() which returns a Map of name/value pairs.
If you need something even more dynamic, try using groovy instead of java. Then you can MetaProgram your way out of any dilemma!
Answering a question here at SO, I came up to a solution which would be nice if it would be possible extend the Class class:
This solution consisted on trying to decorate the Class class in order to allow only certain values to be contained, in this case, classes extending a concrete class C.
public class CextenderClass extends Class
{
public CextenderClass (Class c) throws Exception
{
if(!C.class.isAssignableFrom(c)) //Check whether is `C` sub-class
throw new Exception("The given class is not extending C");
value = c;
}
private Class value;
... Here, methods delegation ...
}
I know this code does not work as Class is final and I wonder why Class is final. I understand it must have to do with security but I can't imagine a situation where extending Class is dangerous. Can you give some examples?
By the way, the closer solution for the desired behavior I can reach is:
public class CextenderClass
{
public CextenderClass(Class c) throws Exception
{
if(!C.class.isAssignableFrom(c)) //Check whether is `C` sub-class
throw new Exception("The given class is not extending C");
value = c;
}
public Class getValue() {
return value;
}
private Class value;
}
But it lacks the beauty of transparent decoration.
According to comments in the Class class Only the Java Virtual Machine creates Class
objects..
If you were allowed to extend classes, then a problem would arise, should you be allowed to create custom Class objects?. If yes, then it would break the above rule that only the JVM should create Class Objects. So, you are not given that flexibility.
PS : getClass() just returns the already created class object. It doesn't return a new class object.
That's a very good question but is only an instance of a more general problem and although #TheLostMind 4 years ago has just responded (considered an implementation point of view) in terms of JVM rules/restrictions the problem still remain: why JVM pose that rules? There have to be a plausible reason. We have to examine it from a more abstract level(point of view)
Short answer:
Plausibly all that has to do with type safety and as all we know Java is a strongly typed language and permits no one to change that fact.
Elaborate Answer(with some context so to be understandable for everyone):
All the story start from static and dynamic binding.
The flexibility given by subtype polymorphism makes the declared (static) type of an object in general different from its run-time (dynamic) type.
The run-time type is in general a subtype of the static type.
e,g.
AClass a = new AClass();
AsubClass b = new AsubClass(); // AsubClass is derived from AClass
a=b;
The static type of a is AClass and after the assignment a=b; its runtime type is AsubClass. This has implications on selection of the most appropriate method when executing a message.
Now consider the class Vehicle given
below.
public class Vehicle {
private int VIN; // Vehicle Identification Number
private String make;
public boolean equals(Object x) {
return (VIN == (Vehicle)x.VIN);
}
// other methods
}
The method equals in the root class java.lang.Object is defined as the test on object identity.
This is the only meaningful way of defining the equality of objects in general.
That is, two objects are equal if they have the same identity.
In a specific class a more suitable meaning of equality may be more appropriate. In the above class two vehicles are considered equal if their VINs (vehicle identification numbers) are equal.
So the method equals is redefined accordingly in the
class Vehicle. This redefinition of an inherited
method is called overriding.
Note that the signatures of the inherited method arguments are required to remain the same in the subclass according to the function subtyping rule.
This creates an awkward situation because in the class Vehicle we would like to refer to the VIN field of the argument, and Object does not have such a field. This is why the type cast (Vehicle)x specifies that the intent is to view x as a Vehicle. There is no way to
verify this cast statically, hence a dynamic check is generated by the compiler. This is an instance of dynamic type checking.
In order for overriding to work correctly the method to be invoked is determined by the dynamic type of the receiver object (also known as dynamic dispatch (selection) of methods and is the most important case of dynamic binding in OO languages.)
e.g.
Object a = new Object();
Object b = new Object();
Vehicle aV = new Vehicle();
Vehicle bV = new Vehicle();
a=aV;
b=bV;
. . .
a.equals(b)
. . .
The method to be invoked in response to the message a.equals(b) will be the method equals overridden in the class Vehicle because the run time type of a is Vehicle.
There are situations in which overriding a method might be problematic and should not be allowed. A good example is the Java.lang.Object 's getClass() . This method has a particular implementation in the underlying virtual platform, which guarantees that invocation of this method will indeed return the class object of the receiver of the method.
Allowing overriding would have serious implications on the intended semantics of this method creating nontrivial problems in dynamic type checking. This is probably why the getClass() is declared as final.
e.g.
public class Object {
public final Class getClass();
....
}
Finally The class Class in Java is final, i.e. cannot be extended, and hence none of its methods can be overridden. Since the class Class has only introspection methods, this guarantees safety of the type system at run-time, i.e., the type information cannot be mutated at run time.
to extend the concept a bit more ...
Dynamic dispatch (selection) of methods based on the type of the receiver object is the basic technique in object-oriented languages.
It brings the type of flexibility that makes the whole object-oriented paradigm work.
Adding new types by inheritance to an already compiled and running application requires only compilation and linking of the newly introduced types without recompiling the existing application. However, this flexibility comes with some penalty in efficiency because the decision about method selection is postponed to runtime. Modern
languages have efficient techniques for dynamic dispatch of methods, but some languages like C++ and C# try to avoid the associated cost by providing a static binding (method selection) option. In C#, methods are statically bound unless they are explicitly declared as virtual.
e.g.
public class Object {
public virtual boolean equals(Object x);
// other methods
}
Overriding this method in C# will be indicated by an explicit keyword override.
e.g.
public class Vehicle {
private int VIN;
private String make;
public override boolean equals(Object x) {
return (VIN == (Vehicle)x.VIN);
}
// other methods
}
Methods whose receiver is the class object are always bound statically.
The reason is that there is only one class object for all objects of that class. Since the receiver is known at compile time, there is no need to postpone method selection to run time. These methods are thus declared as static to indicate that they belong to the class itself.
An example is the method numberOfVehicles of the class Vehicle The number of vehicles is not the property of individual vehicle objects. It is the
property of all objects of the class Vehicle, hence it belongs to the class itself.
e.g.
public class Vehicle {
// fields;
public static int numberOfVehicles();
// other methods
}
We can summarize all the above discussion as follows:
– The basic mechanism for selecting a method for executing a message (method
dispatch) in object-oriented languages is dynamic. It is based on the run-time type of the receiver object.
– The receiver of a static (i.e. class) method is the class object. Since there is only
one class object of a given type, selection of a static method is static.
– Some languages (C++ and C#) allow a choice of static versus dynamic method dispatch. Although this is done for the reasons of efficiency, it has been shown that when both dispatch mechanisms are used in a program, that may obscure the
meaning of the program.
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.
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.