I am reading the Effective Java
by Joshua Bloch and I have question about Item1 Static Factory Method
.
Quote[Bloch, p.7]
Interfaces cant have static methods,
so by convention, static factory
methods for an interface named Type
are put in non-instantiable class
named Types. For example, the Java
Collections Framework, provide
unmodifiable collections, synchronized
collections, and the like. Nearly all
of these implementations are export
via static factory methods in one
noninstantiable class
(java.util.Collections). The classes
of the returned objects are all
non-public.
Ok. When look at the sources code, I see java.util.Collection
interface and java.util.Collections
class with private constructor (non-instantiable class). and I see that the non-instantiable class Collections has all static methods, just like what Bloch said. But i fail to see the connection between the two classes as Bloch said
Interfaces cant have static methods, so by convention, static factory methods for an interface named Type are put in non-instantiable class named Types.
Can anyone point out the obvious to me?
what is it mean when he said
The classes of the returned objects are all non-public
Here is where I obtain the java sources: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Collection.java?av=f
Interfaces cant have static methods, so by convention, static factory methods for an interface named Type are put in non-instantiable class named Types.
The point is just the plural 's' on "Type[s]". So if your interface is called Foo
and you want to create some implementation called MyFoo
then your factory with the methods to instantiate should be called Foos
by convention.
The classes of the returned objects are all non-public
This means that the classes of objects returned from the factory methods have a private or default visibility modifier as in private class MyFoo{}
so that they can not be instantiated by any other means but their factory methods. Since you can't construct an Object using the new
operator from private inner or package private class out of their scope (reflection aside).
e.g.:
public interface Foo{ //interface without plural 's' (question 1)
public void bar();
}
public abstract class Foos(){ // abstract factory with plural 's' (question 1)
public static Foo createFoo(){
return new MyFoo();
}
private class MyFoo implements Foo{ // a non visible implementation (question 2)
public void bar(){}
}
}
Let's say you have an interface called List
and you want to use the static factory method to create different type of lists. You cannot define the static factory methods in the List
interface because it's an interface. So what you have to do it have a class that return instances of classes that implement List
public class ListFactory{
private ListFactory(){}
public static List makeArrayList(){...}
public static List makeLinkedList(){...}
public static List makeCrazyList(){...}
}
You cannot do this
public interface List{
public static List makeArrayList();
public static List makeLinkedList();
public static List makeCrazyList();
}
Since List
is interface.
So take for example Collections.unmodifiableList(...). It returns some implementation of List. But the implementation class's name is irrelevant. Furthermore, said class is only constructed through the static factory method.
public interface Foo
static public class Factory
public Foo create(){..}
Foo foo = Foo.Factory.create();
1) I don't understand your question here. Collection
is the interface and Collections
has some factory methods like emptyList
2) E.g the List instance that is returned by Collection.emptyList
is an instance of a private class that implements the List
interface.
It simply means that the return type of the static factory methods in Collections
(and other classes like it) are interface types (e.g. List
) rather than specific implementation classes (e.g. java.util.Collections.UnmodifiableList
), which are not visible to users since that would just complicate things and increase the size of the API.