Pattern to create class instances by integer id? - java

I am reading a Stream, which provides an identifier (a simple int). Depending on the int different data follows, which i need to turn into objects. So far i created classes for each object type, and each class provides a read(InputStream input)-method which reads whatever data there is to be read for that kind of object (all object classes inherit from a common base class).
However, there are numerous id's and thus numerous classes. What is the most elegant way to determine and create the instance of the class?
The most naive approach i tried first was to have a switch-case block to create the instances, but i find that it clutters the code (unreasonably). It also forces me to have every class available at compile time.
Second try was to create a map that maps each int to a class and use newInstance() to create the objects. There is still the problem that i need to initialize the map, which still requires that i have every class available at compile time. It more or less just moved the clutter from one place to another.
Removing the compile time dependencies is not required, it would just be a bonus if possible. The main goal is to avoid the boilerplate code.
Constraints: I don't want to add a library to solve this. Reflection is fine with me.

An alternative approach is to still use a Map but essentially use late-binding, if that's preferable. You could even store the config in a properties file like:
1=java.lang.String
2=my.class.Something
...etc...
You then do something like this:
Map<Integer,ObjectFactory> loader = ... // load from properties; fairly trivial
assuming:
public class ObjectFactory {
private Final String className;
private transient Class clazz;
public ObjectFactory(String className) {
this.className = className;
}
public Object createInstance() {
try {
if (clazz == null) {
clazz = Class.forName(className);
}
return clazz.newInstance();
} catch (Exception e) {
throw new IllegalStateExxception("Could not crate " + className, e);
}
}
}

I think your map solution sounds fine, but move the initial map setup out of of the Java code and into a config file. (Class.forName will help here)

You could have a registry with prototypes.
A prototype of each class you want to be able to create (at a point in time) could be added to your registry object at runtime, these prototypes would each have their own unique integer id.
When you want an object of id x, you just ask of your registry object to clone and return the prototype which id is x. (or null if no such prototype is currently registered).
Internally the registry could be a (hash)map for quick retrieval, but it could just as easily be a list of prototypes (Do make sure of course that all prototypes implement a common interface the registry can work with). Best thing is, no need for reflection!

Related

Make factory method more dynamic

I am implementing the factory pattern in my code, so came across one interesting thing in factory that I can replace the if else condition in the factory method with Reflection to make my code more dynamic.
Below is the code for both the designs......
1) With if-else conditions
public static Pizza createPizza(String type) {
Pizza pizza = null;
if(type.equals(PizzaType.Cheese))
{
pizza = new CheesePizza();
}
else if (type.equals(PizzaType.Tomato))
{
pizza = new TomatoPizza();
}
else if (type.equals(PizzaType.Capsicum))
{
pizza = new CapsicumPizza();
}
else
{
try {
throw new Exception("Entered PizzaType is not Valid");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return pizza;
}
2) With Reflection
public static Pizza createPizza(String type) {
Pizza pizza = null;
for(PizzaType value : PizzaType.values())
{
if(type.equals(value.getPizzaTypeValue()))
{
String fullyQualifiedclassname = value.getClassNameByPizzaType(type);
try {
pizza = (Pizza)Class.forName(fullyQualifiedclassname).newInstance();
} catch (InstantiationException | IllegalAccessException
| ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return pizza;
}
Second way looks very good to me as I can make my code more dynamic by using it, as I can create one property file with the names of classes and type associated with it to serve the Open and close a bit more, as if in future owners wants to add more pizzas to PizzaStore then he would just make the entry in the property file and will just create one more subclass of Pizza.
But I read that reflection has many disadvantages mentioned few of them.
It is hack of compiler
Automatic development tools are not able to work with reflections code
It's difficult to debug reflections code
Reflection complicates understanding and navigation in code
Significant performance penalty
So very curious to know that, which design is good, as I am very interested to make my code more and more dynamic.
You can also use a design in the middle. E.g.
public interface Factory<T> {
public T newInstance();
}
public class TomatoPizzaFactory implements Factory<TomatoPizza> {
#Override
public TomatoPizza newInstance() {
return new TomatoPizza();
}
}
public class PizzaFactory {
private Map<String, Factory<? extends Pizza>> factories = new HashMap<String, Factory<? extends Pizza>>();
public PizzaFactory(){
factories.put(PizzaType.Cheese, new CheesePizzaFactory());
factories.put(PizzaType.Tomato, new TomatoPizzaFactory());
}
public Pizza createPizza(String type){
Factory<? extends Pizza> factory = factories.get(type);
if(factory == null){
throw new IllegalArgumentException("Unknown pizza type");
}
return factory.newInstance();
}
}
Implement a DefaultConstructorFactory for simple instantiations.
public class DefaultConstructorFactory<T> implements Factory<T> {
private Class<T> type;
public DefaultConstructorFactory(Class<T> type) {
this.type = type;
}
public T newInstance() {
try {
return type.newInstance();
} catch (InstantiationException e) {
throw new IllegalStateException("Can not instantiate " + type, e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Can not instantiate " + type, e);
}
}
}
But I read that reflection has many disadvantages mentioned few of them.
It is hack of compiler
It can be a hack, but if you are writing infrastructure code you will often use reflections. Especially when you write frameworks that must introspect classes at runtime, because the framework doesn't know the classes it will handle at runtime. Think about hibernate, spring, jpa, etc.
Automatic development tools are not able to work with reflections code
That's true, because you shift a lot of compiler issues to runtime. So you should handle reflection exceptions like a compiler and provide good error messages.
There is also only a little refactoring support in some IDEs. So you must be careful when changing code used by reflection code.
Nevertheless you can write tests to find bugs fast.
It's difficult to debug reflections code
That's also true, because you can't jump into a method directly and you have to investigate the variables to find out which member of which object is accessed.
It is a bit more indirection.
Reflection complicates understanding and navigation in code
Yes, if it is used the wrong way. Only use reflection if you do not know the types you have to handle at runtime (infrastructure or framework code). Don't use reflection if you know the types and you only want to minimize code written. If you want to minimize code written select a better design.
Significant performance penalty
I don't think so. Of course reflection calls are indirect method invokations and thus more code must be executed in order to do the same as a direct method call. But the overhead for this is minimal.
If you use reflection code in factories, the reflection overhead is insignificant compared to the lifetime of the created objects.
Also your reflection code will be JIT optimized. Since Java 1.4 the hot spot compiler will inflate a method that is reflectively called more then 15 times by generating a pure-java accessor.
See:https://blogs.oracle.com/buck/entry/inflation_system_properties, https://stackoverflow.com/a/7809300/974186 and https://stackoverflow.com/a/28809546/974186
Frameworks use reflection and generate a lot of proxies that use reflection, e.g. spring's transaction management, jpa, etc. If it would have a significant performance impact all applications using these frameworks would be very slow, wouldn't they.
Using reflection this way is not recommended in general,
but if creating objects dynamically is a top priority in your design,
then it can be acceptable.
Another good option might be to not use different Pizza subtypes,
but a single Pizza class that can be parameterized.
That would make a lot of sense,
since I don't think pizzas behave so very differently.
It seems to me that a diverse range of pizzas could be easily created using the builder pattern.
Btw, another bad practices catches the eye here,
that the parameter of the factory method is a String,
when you actually seem to have PizzaType which is an enum,
and you compare the String parameter to enum values.
It would be much better to use enum values as the parameter,
and a switch instead of the chained if-else.
But, another problem here is that the enum duplicates the available pizza types. So when you add a new pizza type, you also have to update the enum, and the factory method. That's too many files changed. This is code smell.
I suggest to give a try to the single Pizza class and the builder pattern.
Reflection seems like an overkill to me in this situation. Why don't you add a factory method Pizza create(); to your PizzaType interface?
Then just make every implementing class do the initialization, like:
class CheesePizza implements PizzaType {
Pizza create() {
return new CheesePizza();
 }
}
So you only end up with:
for(PizzaType value : PizzaType.values()
if(type.equals(value))
pizza = value.create();
This way the loop in the first example wouldn't be ineffective and it is expandable easily .
Also you shouldn't worry about reflection performance too much, if your code hasn't a need to perform in realtime. I agree, that it makes the code unreadable though, so avoiding it is better in most cases.
Edit: I've overseen, that PizzaType is an enum, not an Interface. In this case you may create one or add a create method to your enum, but I don't think the latter is very favourable.
The if - else statements won't contribute to your design. This merely ensures that the pizza's exist - in a inheritance hierarchy. Try to use a decorator pattern to minimise the hierarchy levels and use a concrete class (like: plainPizza) to add your decorations to.
The decorator pattern is aimed at adding decorations dynamically in run-time.
If you have only few classes returned by factory (let's say three or four) you should just leave it in simplest form with if statements
if(type.equals("someType"){
return new SomeType();
} else if(type.equals("otherType"){
return new OtherType();
}
If you have more class types or you predict frequent changes in this hierarchy then you should switch to implementation where factory class will have collection of available implementations. Your factory class will have field with possible instance types.
public class MyFactory{
private Map<String, Class<? extends ReturnedClass> availableTypes;
}
It might be problematic how to fill this map with elements.
You may:
Hardcode them inside constructor/ init method inside Factory. Note: each new added class will require changes in factory.
Make method registerNewReturnedType(Class c) inside factory. Each returned class will have to register itself inside factory. Note: after adding new class you will not have to change factory
(Recommended) Use dependency injection to fill map.

what is the difference in java objects created with "new" and the ones that do not use "new"

What is the difference between creating an object with and without "new"?
example:
Thing someThing = new Thing();
vs.
Path filePath = Path.get("C:\\......)
In the first example I understand that when instantiating the object, that "new" is allocating memory for a the someThing object and that the memory location is referenced by someThing.
My text book says " You create a Path object" by using the second example. Is the difference just how the object is stored or memory is allocated? I am not sure why you would create an object this way.
In the second case you are using a static method which is internally creating the object or passing a reference to an existing object. This is a common pattern particularly when the APIs wish to hide an internal implementation (as is the case here).
There is no difference. The second example is a factory method.
You pass in a few parameters and that method will call new at some point on the actual instance class of the Path.
While it behaves like a constructor, there are also differences which should be pointed out: Static factory methods do not have to return the current type, but can also return a subtype, where in contrast a constructor creates an instance of the current class. (Hypothetical) Example:
public static Path create(String name) {
return new AbsolutePath(name); // subclass/implementation of Path
}
From an implementation point, this gives you a lot of flexibility for later extensions. You can for example implement some logic, which decides which concrete type to create within the method. You could cache instances and return them. You could return the same instance every time (Singleton). Etc.
Further aspect: You can actually give meaningful names to static factory methods, so code is easier to read:
public static Path createAbsolute(String name) { ... }
public static Path createRelative(String name) { ... }
With the first option you are sure you are creating a new object (more or less, java.lang.* classe are a bit special)
Let's take the second option:
Path filePath = Path.get("C:\\......)
Nothing assures you the instance you are storing in filePath is a Path one, it can be an instance of a subclass of Path. Something similar occurs with Calendar: Calendar is an abstract class, so
Calendar c=Calendar.getInstance();
The variable c is actually a GregorianCalendar.
Another difference:
class Singleton {
private Singleton s=null;
private Singleton(){};
public static Singleton getSingleton() {
if (s==null) {
s=new Singleton();
}
return s;
}
}
No matter how many times you call getSingleton, you will only create one object.
when you are using new keyword then an object of the particular class is created.
Here Thing someThing = new Thing();
something is an object of Thing class
Path filePath = Path.get("C:\......)
Path is a class having static method get() which accepts String arguments and it returns Path something like
public static Path get(String arg)
{
return path;
}
The memory is allocated by the method call to Path.get in the second instance. This allows the library to go through its own initialisation routines for a Path variable and which may perform additional checks. New just allocates memory. The memory may also be sorted and stored internally in some structure too, such that it doesn't constantly reload the same object via caching. I, personally, always call the factory methods rather than new up an object myself, however it could be considered to be a style thing, as pretty much everything that may be done with a factory method may also be achieved via a constructor.
In your examples, you are assuming that an object is created without a "new". That is an incorrect assumption. The object was created with "new" in the second example as well.
Just because you can't see the "new" doesn't mean it's not called in the function.

How to detect if class is injectable

I am using Java Reflection to initialize different types of objects. All of these objects are constructed the same way (namely, I pass in the same values to construct them).
Thus, my injector looks through each of the fields, and does a long if/else statement like the following:
if (Foo.class.isAssignableFrom(field.getType())
return new Foo(values);
else if (Bar.class.isAssignableFrom(field.getType())
return new Bar(values);
else if...//Continue over and over
I can't define an interface that requires the class to have a factory, because factories are static by nature. The same holds true for extending an abstract class.
Is there some way I can remove the above if/else statement so my injecting class has no idea about the classes that need injecting (besides the fact that it can be constructed with values?
As requested:
Have you looked at the Spring source code? This is a problem that has already been solved by an existing open source project and you can just fork the code and re-use it.
Use something like (untested):
private <T> T newInstance(Class<T> type){
Constructor<T> constructor = type.getConstructor(valueTypes);
return constructor.newInstance(values)
}
Then call:
Object obj = newInstance(field.getType());
where valueTypes are the types of the values.

How to remove the dependency on a Java enum's values?

[Mind the gap: I know that the best solution would be to get rid of the enum completely, but that's not an option for today as mentioned in the comments, but it is planned for the (far) future.]
We have two deployment units: frontend and backend. The frontend uses an enum and calls an EJB service at the backend with the enum as a parameter. But the enum changes frequently, so we don't want the backend to know its values.
String constants
A possible solution would be to use String constants insteadof enums, but that would cause a lot of little changes at the frontend. I'm searching a solution, which causes as few changes as possible in the frontend.
Wrapper class
Another solution is the usage of a wrapper class with the same interface as an enum. The enum becomes an wrapper class and the enum values become constants within that wrapper. I had to write some deserialization code to ensure object identity (as enums do), but I don't know if it is a correct solution. What if different classloaders are used?
The wrapper class will implement a Java interface, which will replace the enum in the backend. But will the deserialiaztion code execute in the backend even so?
Example for a wrapper class:
public class Locomotion implements Serializable {
private static final long serialVersionUID = -6359307469030924650L;
public static final List<Locomotion> list = new ArrayList<Locomotion>();
public static final Locomotion CAR = createValue(4654L);
public static final Locomotion CYCLE = createValue(34235656L);
public static final Locomotion FEET = createValue(87687L);
public static final Locomotion createValue(long type) {
Locomotion enumValue = new Locomotion(type);
list.add(enumValue);
return enumValue;
}
private final long ppId;
private Locomotion(long type) {
this.ppId = type;
}
private Object readResolve() throws ObjectStreamException {
for (Locomotion enumValue : list) {
if (this.equals(enumValue)) {
return enumValue;
}
}
throw new InvalidObjectException("Unknown enum value '" + ppId + "'");
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (ppId ^ (ppId >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Locomotion)) {
return false;
}
Locomotion other = (Locomotion) obj;
if (ppId != other.ppId) {
return false;
}
return true;
}
}
Did you already had the same problem? How did you solved it?
Ok, let me see if I understand. You said that
"The frontend uses an enum and calls
an EJB service at the backend with the
enum as a parameter. But the enum
changes frequently, so we don't want
the backend to know its values"
When you say "values" I assume you are referring to the numeric value you pass in the enum constructor and not to the enum constants themselves.
Therefore, this implies that the frontend and the backend will have two different versions of the enum class, but the enum constants in them will be the same.
I am only assuming the communication is via RMI (but this is not entirely clear in your post).
Now, serialization/deserialization of enums works different than with other objects. According to the Java Serialization Specification, when a enum is serialized, only its name is serialized. And when it is deserialized, it is built using the Enum.valueOf(name) method.
So, your original wrapper proposal would not work, because the server, due to stipulated serialization of Enums will never know the actual value of the enums in the client.
Bottom line, if you intend to pass an enum to the server there is no possible way to do what you pretend to do because the values in the frontend will never reach the backend if serialization is implied.
If RMI is implied, a good solution would be to use code mobility, this way you could place the problematic class in a repository accessible to both, server and client, and when the frontend developers change the class definition, you can publish the class in the repository and the server can get it from there.
See this article about dynamic code downloading using code base property in RMI
http://download.oracle.com/javase/6/docs/technotes/guides/rmi/codebase.html
Another possible solution is that you could stop using a Java Enum and use Java class with final constants, as we used to do in the old days before enums, and that way you can ensure that its values will be properly serialized when they are are sent to the backend.
Somewhat like this
public class Fruit implements Serializable{
private static final long serialVersionUID = 1L;
public final Fruit ORANGE = new Fruit("orange");
public final Fruit LEMON = new Fruit("lemon");
private String name;
private Fruit(String name){
this.name = name;
}
}
This way you can be in full control of what happens upon deserialization and your wrapper pattern might work this way.
This type of construction cannot substitute an enum completely, for instance, it cannot be used in switch statements. But, if this is an issue, you could use this object as the parameter sent to the server, and let the server rebuild the enum out of it with its version of the enum class.
Your enum, therefore, could have two new methods, one to build Java instances out of the enum itself:
public static Fruit toFruit(FruitEnum enum);
public FruitEnum valueOf(Fruit fruit);
And you can use those to convert back and forth versions of the parameter for the server.
It's an odd request, as i would think the server should know about the values of what is going into the database, but ok, i'll play along. Perhaps you could do this
public enum Giant {Fee, Fi, Fo, Fum};
public void client() {
Giant giant = Giant.Fee;
server(giant);
}
public void server(Enum e) {
String valueForDB = e.name();
//or perhaps
String valueForDB = e.toString();
}
For data transfer between frontend and backend both need to use the same class versions because of possible serialization during marshalling parameters. So again they have to know exactly the same enums or whatever other classes you try to use. Switching enums to something different won't work either. You have to set on a known class identiy for both.
So if the server should do actions based on some kind of processing/calculating the values of the parameters use strings or whatever other non-changing class you decide on and put your values inside: string of characters, array of numbers or whatever.
So if you put your database id inside the wrapper object the server will be able to get the objects out of the database. But still - they both need exact the same version of the wrapper class in their classpaths.
Okay, I can't be too exact because I don't see your code but in my experience something that changes like that should be external data, not enums.
What I almost always find is that if I externalize the information that was in the enums, then I have to externalize a few other pieces as well, but after doing it all I end up factoring away a LOT of code.
Any time you actually use the values of an enum you are almost certainly writing duplicate code. What I mean is that if you have enums like "HEARTS", "DIAMONDS"...
The ONLY way they can be used in your code is in something like a switch statement:
switch(card.suit)
case Suit.HEARTS:
load_graphic(Suit.HEARTS);
// or better yet:
Suit.HEARTS.loadGraphic();
break;
case Suit.SPADES:
Suit.SPADES.loadGraphic();
...
Now, this is obviously stupid but I made the stupid constraint to say that you USED the values in the code. My assertion is that if you don't USE the values you don't need an enum--Let's not use the values in code and see:
card.suit.loadGraphic();
Wow, all gone. But suddenly, the entire point of using an enum is gone--instead you get rid of the whole class preload a "Suit" factory with 4 instances from a text file with strings like "Heart.png" and "Spade.png".
Nearly every time I use enums I end up factoring them out like this.
I'm not saying there isn't any code that can benefit from enums--but the better that I get at factoring code and externalizing data, the less I can imagine really needing them.

Is it possible to load one of two different classes in Java with the same name?

I have a lot of code that calls static methods on Foo like "Foo.method()". I have two different implementations of Foo and would like to use one or the other depending on the circumstances. In psuedocode:
File Foo1.java
class Foo1 implements Foo {
public static int method() {
return 0;
}
}
File Foo2.java
class Foo2 implements Foo {
public static int method() {
return 1;
}
}
File Main.java
if(shouldLoadFoo1()) {
Foo = loadClass("Foo1");
} else {
Foo = loadClass("Foo2");
}
Is this possible with Java metaprogramming? I can't quite wrap my head around all the dynamic class loading documentation. If not, what's the best way to do what I'm trying to do?
Essentially you have two classes with the same interface but different implementations,Wouldn't it be better to do it using an interface?
in your main class, depending on the circumstances you would construct your class with the appropriate instance.
FooInterface foo;
MainClass (FooInteface foo, other fields) {
this.foo = foo;
}
....
then just use foo from them on.
Another way is to use AspectJ, define a point cut on every Foo.method call, in in the advice for the point cut have your if (shouldLoadFoo1()) { Foo1.method()} etc ..
The typical approach to exchanging implementations is to use a non-static method and polymorphism, typically using dependency injection to tell the depedent code the implementation to use.
The next cleanest way is the singleton pattern, i.e. to declare:
public abstract class Foo {
protected abstract void doSomeMethod();
// populated at startup using whatever logic you desire
public static Foo instance;
public static void someMethod() {
instance.doSomeMethod();
}
}
The really hacky way to solve your problem would be what you ask for, i.e. to have two different class files for the same class, and decide at runtime which one to use. To do that, you would seperate your project into 4 different jar files:
loader.jar that determines the classpath to use and constructs the classloader for the actual application. The classes in loader.jar must not reference Foo.
foo1.jar that contains one implementation for Foo
foo2.jar that contains another implementation for Foo
common.jar that contains everything else
Loader.jar would then contain a bootstrap method like:
void bootstrap() {
URL commonUrl = // path to common.jar
URL fooUrl;
if (shouldUseFoo1()) {
fooUrl = // path to Foo1.jar
} else {
fooUrl = // path fo Foo2.jar
}
URL[] urls = {fooUrl, commonUrl};
ClassLoader loader = new UrlClassLoader(urls);
Class<?> mainClass = loader.loadClass("my.main");
mainClass.newInstance(); // start the app by invoking a constructor
}
I am not sure I fully understand the problem here (I see many has that issue), but let me try to help.
If your problem was coming down just to using appropriate function method(), you could create a utility function that depending on an instance of a given class will call appropriate method, e.g.
private static int getResultOfFoo(Foo foo)
{
int res = -1;
if(foo instanceof Foo1)
res = Foo1.method();
else res = Foo2.method();
return res;
}
Otherwise, I agree with Stephen C: "Well, see my answer then. That's the closest you are likely to get in Java."
What you have written doesn't make sense from a linguistic standpoint. Foo is an type, and a type is not a variable and cannot appear on the LHS of an assignment. You cannot treat a type as a value in Java ... the language doesn't allow it.
The closest that you can get to what you are trying to do is something like this:
Class fooClass;
if (loadFoo1) {
fooClass = Class.forName("some.pkg.Foo1");
} else {
fooClass = Class.forName("some.pkg.Foo2");
}
Foo foo = (Foo) fooClass.newInstance(); // using the no-args constructor
(I've left out the exception handling ...)
Note that fooClass will be an instance of the class Class which provides runtime handles that are used for performing operations reflectively. We are NOT actually assigning a type. We are assigning an object that "denotes" a type ... in a limited fashion.
HOWEVER ... if you don't need to use dynamic loading you should not use it. In other words, if the underlying problem that you are trying to solve is creating instances of classes that could be statically loaded, then it is better to use the factory pattern; see #andersoj's answer for example.
UPDATE
I just figured out what you are probably trying to do here. That is, you are trying to figure out a way to choose between different static methods (i.e. Foo1.method() and Foo2.method()) without explicitly naming the classes at the point where the call is made.
Again, what you are trying to do simply won't work in Java:
You cannot declare a static method in an interface.
You cannot call a static method in an implementation class via the interface.
Static method calls are not "dispatched" in Java. They are bound statically.
There is a way to do something roughly like this using reflection; e.g.
Class fooClass;
// Load one or other of the classes as above.
Method m = fooClass.getDeclaredMethod("method");
Integer res = (Integer) m.invoke(null);
(As before, I've left out the exception handling)
Once again you would be much better off doing this without resorting to dynamic loading and reflection. The simple approach would be to create a helper method like this in some utilities class:
public static int method() {
return useFoo1 ? Foo1.method() : Foo2.method();
}
Better still, do it the OO way: declare method in the Foo interface as a instance method, create a singleton or an injected instance of Foo1 or Foo2, and rely on polymorphism.
But the take away is that there is NO WAY to avoid changing all of the places in your codebase where method() is called ... if you want to be able to choose between Foo1.method and Foo2.method at runtime.
You can use a factory pattern to do this.
static Foo makeMeAFoo()
{
final Foo foo;
if(shouldLoadFoo1()) {
foo = new Foo1();
} else {
foo = new Foo2();
}
return foo;
}
Which is I think what you're asking for. Though I like hhafez' suggestion better myself.
(Note my answer is now OBE b/c the questioner shifted the methods to be static rather than instance methods. Nevertheless, the tone of other answerers is good... solving this problem by explicit classloading just because you want to select specific static methods is a kludge.)
In your example you in fact have not two different versions of class Foo, but two different implementations of the interface Foo, which is fine in most cases. (They even can exist parallel to each other.)
It is possible to load multiple classes of the same name, but they have to be loaded by different classloaders. This also means that you can't have a third class referencing it by name and then using one or the other (without the third class also being on two classloaders).
Sometimes it may be sensible to have different versions of a class (with same external interface) for different configurations where it would be used (such as "on client side" / "on server side", when some common class in both modules depends on it), and in rare cases you would have both modules in the same VM at the same time - but in most cases it would be better to use the "one interface and multiple implementing classes" approach instead.

Categories