Ok, the question might not be crystal clear. Let me give some details:
Let's say I have an Shoe (CShoe) object factory class called CFactory. CFactory is a singleton class that creates and stores all instanciated shoes using a simple hashmap. It is then accessed through static methods to use the created objects.
Is there a way to force CShoe's constructor so that it can only called by the factory? (in other words, ensure that the creation of shoes can only be done by the shoes factory singleton class and not by other classes)
No, Constructors can be public , private , protected or default (no access modifier at all). Making something private doesn't mean nobody can access it. It just means that nobody outside the class can access it. So private constructor is useful too.
A factory constructor is a constructor that can be used when you don't necessarily want a constructor to create a new instance of your class. This might be useful if you hold instances of your class in memory and don't want to create a new one each time (or if the operation of creating an instance is costly).
A constructor is concrete in that it creates objects as instances of a single class, and by a specified process (class instantiation), while a factory can create objects by instantiating various classes, or by using other allocation schemes such as an object pool.
You could make Shoe
an inner class
of ShoeFactory
:
public class ShoeFactory {
public static class Shoe {
private String name;
private Shoe() {
}
private Shoe(String name) {
this.name = name;
}
}
public static Shoe createShoe(String shoeName) {
return new Shoe(shoeName);
}
}
I think this pretty much covers all the cases except .... reflection:
public class SmellyShoe {
public static void main(String[] args) {
try {
java.lang.reflect.Constructor c = Shoe.class.getDeclaredConstructors()[0];
c.setAccessible(true);
Shoe smelly = (Shoe)c.newInstance(null);
// grr
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
You could give the CShoe constructor package access, and put both CShoe and CFactory in the same package.
Since you want to add each object to the map you could as well move this logic to the CShoe constructor - the object will add itsself.
Firstly, if you retain all created instances, that's known as a leak. I'll carry on assuming you mean a non-strong reference, bounded or some such cache, and also that Shoe
is immutable.
Simply use a static
method to return the factory.
public final class Shoe implements Footwear {
private static final FootwearFactory<Shoe,Something> FACTORY =
new FootwearFactory<Shoe,Something>() {
...
public Shoe get(Something value) {
value = new Something(value);
...
return new Show(value);
}
};
private static FootwearFactory<Shoe,Something> getFactory() {
return FACTORY;
}
private final Something value;
private Shoe(Something value) {
this.value = value;
}
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With