static factory method in interface class java - java

I was reading Effective java text book. First item is about using static factory methods instead of public constructor. My doubt is that if i am specifying an Interface how can i specify a static factory method in the Interface ? Because java does not support static methods inside interface. The text book specifies about creating a non-instantiable class containing the public static factory methods. But how can those method access the private constructor of the implementation class?
The text book says if you are defining an Interface Type , create a non-instantiable class Types and include the static factory methods in that class. But how can a method defined in the Types class access the private constructor of a concrete implementation of Interface Type
EDIT:- Below sentence is quoted from the text book. Please explain me its meaning
"Interfaces can’t have static methods, so by convention, static factory methods for an interface named Type are put in a noninstantiable class (Item 4) named Types "
EDIT:- taken from Effective Java By Joshua Bloch: Item1 - Static Factory Method
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(){}
}
}
My question is that how can the static method createFoo() calls the private constructor of MyFoo

You can define the factory as returning the Interface but internally it creates a concrete class.
For example:
public Interface I { }
private class Impl implements I {
}
I buildI() {
return new Impl();
}
The trick is to create the implementations with package private (or even if they are inner classes private) constructors and then only the factory can build them.
The power of this method is that the factory can build the appropriate implementation depending on the requirements and that all happens invisibly to the user. For example when you create an EnumSet using the factory there are multiple internal implementations depending on how many entries there are in the Enum that the EnumSet is being built for. A super-fast version using bitfields on a long for Enums with less than 64 entries, a slower version for longer enumerations.
To specify the interface for a factory all you need to do is:
public interface Factory {
I buildI();
}
Now people can call you with setFactory(new FactoryImpl()); you can then call factory.buildI() and their code then returns the concrete implementation.
You can take this a step further and use Generics:
public interface GenericFactory<T> {
T buildInstance();
}
And then your setFactory becomes:
public void setFactory(GenericFactory<I> factory);
To create a factory they do:
public class FactoryImpl implements GenericFactory<I> {
#override
I buildInstance() {
return new impl();
}
}
But now you can use that same factory class for absolutely anything that needs a factory, just change the generics requirement.
The reason it can call the private constructor is very simple - it's declared in the same class!
Inside one Java file you can create the class with the private constructor. You then define the static method inside the class and even though it is static it still has the privileges required to access the constructor.
If the factory and implementation are in separate classes then they will be placed in the same package and the method made package private instead of private.

Java 8 finally allows interfaces to have static methods.
See this archived copy of the TechEmpower blog for details.

One way to think about this is with the package encapsulation in mind. Consider this Java 9+ code:
public interface Engine {
void start();
static Engine getEngine(String type) {
switch (type) {
case "combustion":
return new CombustionEngine();
case "electric":
return new ElectricEngine();
default:
throw new IllegalArgumentException("Unknown engine type : " + type);
}
}
}
class CombustionEngine implements Engine {
CombustionEngine() {
}
#Override
public void start() {
// injecting fuel and igniting it to create combustion...
}
}
class ElectricEngine implements Engine {
ElectricEngine() {
}
#Override
public void start() {
// electric current from battery flowing through coil in magnetic field...
}
}
Note that constructors in implementations are package-private so the caller from a different package can't instantiate implementation directly and should use the factory method.
Having the factory method in the interface
has no need for a dedicated EngineFactory class (the traditional implementation of Factory method design pattern)
reminds to Program to interface, not implementation
If needed, there is also a way to create implementation instances as singletons, which improves memory footprint :
public interface Engine {
enum EngineType {
COMBUSTION,
ELECTRIC;
private static EnumMap<EngineType, Engine> MAP = new EnumMap<>(EngineType.class);
static {
MAP.put(COMBUSTION, new CombustionEngine());
MAP.put(ELECTRIC, new ElectricEngine());
}
}
void start();
static Engine getEngine(EngineType type) {
return EngineType.MAP.get(type);
}
}

You cannot define a factory method in an interface, but you cannot have a constructor in an interface either: Interfaces cannot be instantiated. The point is to use a factory method instead of a constructor in the classes implementing the interface, not in the interface itself.

It talks about creating object via static factory method in the implementation not the interface
public Interface MyInterface {
public void myFunction();
}
public class MyClass implements MyInterface {
// constructor is made private
private MyClass() {}
// Use this to create object instead use static factory
public static MyClass getInstance() {
return new MyClass();
}
public void myFunction(){
// your implementation
}
}
A previous post also talks about static factory method.. What are static factory methods?
Apart from the book I also find the undermentioned link a good read
http://www.javacodegeeks.com/2013/01/static-factory-methods-vs-traditional-constructors.html

Related

How do i ensure implementation of a public static function with interface

Since Java 8, we are able to define static and default methods in interface. But I need to ensure a public static method say foo() to be implemented in all the classes that implements a particular interface say interface A. How do I do that , or is it at all possible ?
The interface A:
package com.practice.misc.interfacetest;
public interface A {
public static Object foo(); //Eclipse shows error : 'This method requires a body instead of a semicolon'
String normalFunc();
}
Class B :
package com.practice.misc.interfacetest;
public class B implements A{
#Override
public String normalFunc() {
return "B.normalFunc";
}
//I need to ensure that I have to define function foo() too
}
Class C :
package com.practice.misc.interfacetest;
public class C implements A{
#Override
public String normalFunc() {
return "C.normalFunc";
}
//I need to ensure that I have to define function foo() too
}
Edit 1:
Actual case :
I have one public static method getInstance() (returning Singleton instance of that class) in all the implementing classes, and I want to ensure all the future classes other developers write must have that static method implemented in their classes. I can simply use reflection to return that instance by calling the getInstance() method from a static method of the interface, but I wanted to make sure that everyone implements the getInstance() in all the implementing classes.
static methods from interface are not inherited (1). They are inherited in case of a class, but you can not override them (2); thus what you are trying to do is literally impossible.
If you want all classes to implement your method, why not simply make it abstract (and implicitly public) to begin with, so that everyone is forced to implement it.
Eugene already pointed out that static methods can not be overridden. I suggest that you extract the singleton behavior to a separate interface. For example:
public interface A {
String normalFunc();
}
public class B implements A {
#Override
public String normalFunc() {
return "B.normalFunc";
}
// TODO add getInstance for singleton
}
public interface Singleton {
// TODO extensive javadoc to describe expected singleton behavior
A getInstance();
}
public class BSingleton implements Singleton {
#Override
public A getInstance() {
return B.getInstance();
}
}
Finally you can use any object of type BSingleton to get the singleton object of B.

Return a private class implementing an interface keeping the implementation private

Static method M returns an object implementing interface A:
interface A { ... }
static A M() { ... }
Within M I would like to construct an object of type B and return that, given that B implements A:
class B implements A { ... }
I do not want client code to know anything about how B is implemented, I would prefer for B not to be a static class, B must be immutable and there could be different B handed to different clients. I want to prevent instantiation of B outside method M at all costs (short of reflection, as one user commented).
How can I achieve the above? Where and how should I implement B? Could you please provide a short code example?
My main problem is: how can I have "different Bs?"
A static inner class is probably your best bet. You won't be able to "prevent instantiation of B at all costs" since with reflection, client code can bypass all access modifiers.
You can use anonymous inner class that won't be called B (is anonymous) but will implement A for example
interface A {
void someMethod();
}
public class Test {
static A M() {
return new A() {// it will create and return object of anonymous
// class that implements A
#Override
public void someMethod() {
}
};
}
}
Without using reflection object of anonymous class can be created only by method M. Also it can't be extended so it is good first step to immutability.
You could also use a Proxy implementation to hide the implementation class further
public interface A {
public Object getValue();
}
public class Factory {
public static A newInstance() {
return new ProxyA(AImpl);
}
}
public class ProxyA implements A {
private A proxy;
public ProxyA(A proxy) {
this.proxy = proxy;
}
public Object getValue() {
return proxy.getValue();
}
}
All this is really doing is hiding the implementation of A under another layout and makes it difficult to create a instance of ProxyA
But as #Asaph points out, with reflection, it becomes next to near impossible to truly guard against people accessing various parts of the classes and objects...
You could also separate your interface and implementations via different Classloaders, so that you only ever expose the interface's to the developers and implementations are delivered by dynamic class loading them at runtime. While not solving the underlying problem, it further complicates the matters for those trying to circumvent your factory.
IMHO

How to refactor a class hierarchy of singletons where each class has a getInstance() method?

I have inherited a particular class hierarchy of singletons whose declarations are summarized below (there are more implementations -- I'm just showing the minimal set to demonstrate the problem). It smells to high heaven to me, foremost because singletons are being inherited from, as well as the way instance in the base class has its value overwritten in the static initializers of the subclasses.
If all the implementations were in the foo.common parent package I would consider just dropping the instance member and getInstance() methods from them, making the classes and their constructors package-local, and having some public factory class in foo.common create a single instance of each, hold onto that single instance of each internally (partitioned by whether it was an implementation of IReadOnly or IReadWrite) and provide a couple of public lookup methods where based on some enum it would return the asked-for implementation as the interface type.
But implementations can be outside of foo.common and foo.common isn't allowed to depend on such "more specific" packages, since foo.common is intended for stuff common to a bunch of apps. So something that simple can't be done. What then?
First interface:
package foo.common.config;
public interface IReadOnly
{
void load();
String getVal(String key);
}
Second interface:
package foo.common.config;
public interface IReadWrite extends IReadOnly
{
void save();
void setVal(String key, String value);
}
First implementation:
package foo.common.config;
public class ReadOnlyImpl implements IReadOnly
{
protected static IReadOnly instance;
static {
instance = new ReadOnlyImpl();
}
public static IReadOnly getInstance() {
return instance;
}
protected ReadOnlyImpl() {}
// implement methods in IReadOnly
}
Second implementation
package foo.common.config;
public class ReadWriteImpl extends ReadOnlyImpl implements IReadWrite
{
static {
instance = new ReadWriteImpl();
}
public static IReadWrite getInstance() {
return (IReadWrite) instance;
}
protected ReadWriteImpl() {
super();
}
// Implement methods in IReadWrite
}
Third implementation:
// While things in this package can depend
// on things in foo.common, nothing in
// foo.common is allowed to depend on this package.
package foo.apps.someapp;
public class MoreSpecificReadWriteImpl extends ReadWriteImpl
{
static {
instance = new MoreSpecificReadWriteImpl();
}
public static IReadWrite getInstance() {
return (IReadWrite) instance;
}
protected MoreSpecificReadWrite() {
super();
}
// Override superclass methods to do something specific
}
Putting package foo.apps.someapp aside, the design of the package foo.common.config is wrong.
IReadOnly o1=ReadOnlyImpl.getInstance(); // ok, returns ReadOnlyImpl
...
ReadWrite o2=ReadWriteImpl.getInstance(); // ok, returns ReadWriteImpl
...
IReadOnly o3=ReadOnlyImpl.getInstance(); // bad, returns ReadWriteImpl, the same as o2.
The reason is that all classes use the same static variable ReadOnlyImpl.instance. I would use separate variable in all classes, including MoreSpecificReadWriteImpl. If this would not fit, then think of using Spring container or similar framework.

Practical side of the ability to define a class within an interface in Java?

What would be the practical side of the ability to define a class within an interface in Java:
interface IFoo
{
class Bar
{
void foobar ()
{
System.out.println("foobaring...");
}
}
}
I can think of another usage than those linked by Eric P: defining a default/no-op implementation of the interface.
./alex
interface IEmployee
{
void workHard ();
void procrastinate ();
class DefaultEmployee implements IEmployee
{
void workHard () { procrastinate(); };
void procrastinate () {};
}
}
Yet another sample — implementation of Null Object Pattern:
interface IFoo
{
void doFoo();
IFoo NULL_FOO = new NullFoo();
final class NullFoo implements IFoo
{
public void doFoo () {};
private NullFoo () {};
}
}
...
IFoo foo = IFoo.NULL_FOO;
...
bar.addFooListener (foo);
...
I think this page explains one example pretty well. You would use it to tightly bind a certain type to an interface.
Shamelessly ripped off from the above link:
interface employee{
class Role{
public String rolename;
public int roleId;
}
Role getRole();
// other methods
}
In the above interface you are binding the Role type strongly to the employee interface(employee.Role).
One use (for better or worse) would be as a workaround for the fact that Java doesn't support static methods in interfaces.
interface Foo {
int[] getData();
class _ {
static int sum(Foo foo) {
int sum = 0;
for(int i: foo.getData()) {
sum += i;
}
return sum;
}
}
}
Then you'd call it with:
int sum = Foo._.sum(myFoo);
I can say without hesitation that I've never done that. I can't think of a reason why you would either. Classes nested within classes? Sure, lots of reasons to do that. In those cases I tend to consider those inner classes to be an implementation detail. Obviously an interface has no implementation details.
One place this idiom is used heavily is in XMLBeans. The purpose of that project is to take an XML Schema and generate a set of Java classes that you can use bidirectionally to work with XML documents corresponding to the schema. So, it lets you parse XML into xml beans or create the xml beans and output to xml.
In general, most of the xml schema types are mapped to a Java interface. That interface has within it a Factory that is used to generate instances of that interface in the default implementation:
public interface Foo extends XmlObject {
public boolean getBar();
public boolean isSetBar();
public void setBar(boolean bar);
public static final SchemaType type = ...
public static final class Factory {
public static Foo newInstance() {
return (Foo)XmlBeans.getContextTypeLoader().newInstance(Foo.type, null);
}
// other factory and parsing methods
}
}
When I first encountered this it seemed wrong to bind all this implementation gunk into the interface definition. However, I actually grew to like it as it let everything get defined in terms of interfaces but have a uniform way to get instances of the interface (as opposed to having another external factory / builder class).
I picked it up for classes where this made sense (particularly those where I had a great deal of control over the interface/impls) and found it to be fairly clean.
I guess you could define a class that is used as the return type or parameter type for methods within the interface. Doesn't seem particularly useful. You might as well just define the class separately. The only possible advantage is that it declares the class as "belonging" to the interface in some sense.
Google Web Toolkit uses such classes to bind 'normal' interface to asynchronous call interface:
public interface LoginService extends RemoteService {
/**
* Utility/Convenience class.
* Use LoginService.App.getInstance() to access static instance of LoginServiceAsync
*/
class App {
public static synchronized LoginServiceAsync getInstance() {
...
}
}
}
With a static class inside an interface you have the possibility to shorten a common programming fragment: Checking if an object is an instance of an interface, and if so calling a method of this interface. Look at this example:
public interface Printable {
void print();
public static class Caller {
public static void print(Object mightBePrintable) {
if (mightBePrintable instanceof Printable) {
((Printable) mightBePrintable).print();
}
}
}
}
Now instead of doing this:
void genericPrintMethod(Object obj) {
if (obj instanceof Printable) {
((Printable) obj).print();
}
}
You can write:
void genericPrintMethod(Object obj) {
Printable.Caller.print(obj);
}
Doing this seems to have "Bad design decision" written all over it.
I would urge caution whenever it seems like a good idea to create a non-private nested class. You are almost certainly better off going straight for an outer class. But if you are going to create a public nested class, it doesn't seem any more strange to put it in an interface than a class. The abstractness of the outer class is not necessarily related to the abstractness of a nested class.
This approach can be used to define many classes in the same file. This has worked well for me in the past where I have many simple implementations of an interface. However, if I were to do this again, I would use an enum which implements an interface which would have been a more elegant solution.

Why can't I declare static methods in an interface?

The topic says the most of it - what is the reason for the fact that static methods can't be declared in an interface?
public interface ITest {
public static String test();
}
The code above gives me the following error (in Eclipse, at least): "Illegal modifier for the interface method ITest.test(); only public & abstract are permitted".
There are a few issues at play here. The first is the issue of declaring a static method without defining it. This is the difference between
public interface Foo {
public static int bar();
}
and
public interface Foo {
public static int bar() {
...
}
}
The first is impossible for the reasons that Espo mentions: you don't know which implementing class is the correct definition.
Java could allow the latter; and in fact, starting in Java 8, it does!
The reason why you can't have a static method in an interface lies in the way Java resolves static references. Java will not bother looking for an instance of a class when attempting to execute a static method. This is because static methods are not instance dependent and hence can be executed straight from the class file. Given that all methods in an interface are abstract, the VM would have to look for a particular implementation of the interface in order to find the code behind the static method so that it could be executed. This then contradicts how static method resolution works and would introduce an inconsistency into the language.
I'll answer your question with an example. Suppose we had a Math class with a static method add. You would call this method like so:
Math.add(2, 3);
If Math were an interface instead of a class, it could not have any defined functions. As such, saying something like Math.add(2, 3) makes no sense.
The reason lies in the design-principle, that java does not allow multiple inheritance. The problem with multiple inheritance can be illustrated by the following example:
public class A {
public method x() {...}
}
public class B {
public method x() {...}
}
public class C extends A, B { ... }
Now what happens if you call C.x()? Will be A.x() or B.x() executed? Every language with multiple inheritance has to solve this problem.
Interfaces allow in Java some sort of restricted multiple inheritance. To avoid the problem above, they are not allowed to have methods. If we look at the same problem with interfaces and static methods:
public interface A {
public static method x() {...}
}
public interface B {
public static method x() {...}
}
public class C implements A, B { ... }
Same problem here, what happen if you call C.x()?
Static methods are not instance methods. There's no instance context, therefore to implement it from the interface makes little sense.
Now Java8 allows us to define even Static Methods in Interface.
interface X {
static void foo() {
System.out.println("foo");
}
}
class Y implements X {
//...
}
public class Z {
public static void main(String[] args) {
X.foo();
// Y.foo(); // won't compile because foo() is a Static Method of X and not Y
}
}
Note: Methods in Interface are still public abstract by default if we don't explicitly use the keywords default/static to make them Default methods and Static methods resp.
There's a very nice and concise answer to your question here. (It struck me as such a nicely straightforward way of explaining it that I want to link it from here.)
It seems the static method in the interface might be supported in Java 8, well, my solution is just define them in the inner class.
interface Foo {
// ...
class fn {
public static void func1(...) {
// ...
}
}
}
The same technique can also be used in annotations:
public #interface Foo {
String value();
class fn {
public static String getValue(Object obj) {
Foo foo = obj.getClass().getAnnotation(Foo.class);
return foo == null ? null : foo.value();
}
}
}
The inner class should always be accessed in the form of Interface.fn... instead of Class.fn..., then, you can get rid of ambiguous problem.
An interface is used for polymorphism, which applies to Objects, not types. Therefore (as already noted) it makes no sense to have an static interface member.
Java 8 Had changed the world you can have static methods in interface but it forces you to provide implementation for that.
public interface StaticMethodInterface {
public static int testStaticMethod() {
return 0;
}
/**
* Illegal combination of modifiers for the interface method
* testStaticMethod; only one of abstract, default, or static permitted
*
* #param i
* #return
*/
// public static abstract int testStaticMethod(float i);
default int testNonStaticMethod() {
return 1;
}
/**
* Without implementation.
*
* #param i
* #return
*/
int testNonStaticMethod(float i);
}
Illegal combination of modifiers : static and abstract
If a member of a class is declared as static, it can be used with its class name which is confined to that class, without creating an object.
If a member of a class is declared as abstract, you need to declare the class as abstract and you need to provide the implementation of the abstract member in its inherited class (Sub-Class).
You need to provide an implementation to the abstract member of a class in sub-class where you are going to change the behaviour of static method, also declared as abstract which is a confined to the base class, which is not correct
Since static methods can not be inherited . So no use placing it in the interface. Interface is basically a contract which all its subscribers have to follow . Placing a static method in interface will force the subscribers to implement it . which now becomes contradictory to the fact that static methods can not be inherited .
With Java 8, interfaces can now have static methods.
For example, Comparator has a static naturalOrder() method.
The requirement that interfaces cannot have implementations has also been relaxed. Interfaces can now declare "default" method implementations, which are like normal implementations with one exception: if you inherit both a default implementation from an interface and a normal implementation from a superclass, the superclass's implementation will always take priority.
Perhaps a code example would help, I'm going to use C#, but you should be able to follow along.
Lets pretend we have an interface called IPayable
public interface IPayable
{
public Pay(double amount);
}
Now, we have two concrete classes that implement this interface:
public class BusinessAccount : IPayable
{
public void Pay(double amount)
{
//Logic
}
}
public class CustomerAccount : IPayable
{
public void Pay(double amount)
{
//Logic
}
}
Now, lets pretend we have a collection of various accounts, to do this we will use a generic list of the type IPayable
List<IPayable> accountsToPay = new List<IPayable>();
accountsToPay.add(new CustomerAccount());
accountsToPay.add(new BusinessAccount());
Now, we want to pay $50.00 to all those accounts:
foreach (IPayable account in accountsToPay)
{
account.Pay(50.00);
}
So now you see how interfaces are incredibly useful.
They are used on instantiated objects only. Not on static classes.
If you had made pay static, when looping through the IPayable's in accountsToPay there would be no way to figure out if it should call pay on BusinessAcount or CustomerAccount.

Categories

Resources