public Object foo(int opt){
if (opt == 0) return new String();
else if (opt == 1) return new Integer(1);
else if (opt == 2) return new Double(1);
else if ...
.. and many more
}
public void doSomething(String s){..}
public void doSomething(Integer i){..}
public void doSomething(Double d){..}
... and many more doSomething method
public static void main(String[] args){
...
Object o = foo(x); //x is a value obtained during runtime, e.g. from user input
//now I want to call doSomething method
// (1)
if (o instanceof String) doSomething((String) o);
else if (o instanceof Integer) doSomething((Integer) o);
else if (o instanceof Double) doSomething((Double) o);
...
// (2)
}
Is there any better way to simplify statements enclosed by (1) ... (2)?
Does Java Reflection help?
You can do dynamic casting by calling a method which takes a parameter of the type you want to change your current type to. Take this for example: public class Example{ Example e1=new Example(); private Object obj=new Object(); e1.
Type Casting is a feature in Java using which the form or type of a variable or object is cast into some other kind of Object, and the process of conversion from one type to another is called Type Casting.
You convert an Object variable to another data type by using a conversion keyword such as CType Function.
To create an object dynamically from the class name, you need to use a reflection. If the fully-qualified name of a class is available, it is possible to get the corresponding Class using the static method Class. forName(). However, This cannot be used for primitive types.
The best way to handle this efficiently and cleanly is to have foo return a holder class for the object.
abstract class Holder<T> {
private final T object;
protected Holder(T object) { this.object = object; }
public T get() { return object; }
public abstract void doSomething();
}
public Holder foo(int opt) {
if (opt == 0) return new Holder<String>("") {
public void doSomething() { }
};
else if (opt == 1) return new Holder<Integer>(1) {
public void doSomething() { }
};
else if (opt == 2) return new Holder<Double>(1.0) {
public void doSomething() { }
};
// many more
}
public static void main(String... args) throws IOException {
Holder h = foo(x); //x is a value obtained during runtime, e.g. from user input
//now I want to call doSomething method
h.doSomething();
}
Basically you want overload resolution performed at execution time - you're not going to be able to do that very simply.
In some cases, the visitor pattern can help, but I don't think it would here. I think you're stuck with either the code that you've got here, or reflection. I've never been as keen on the visitor pattern as some of my colleagues - it always feels a little messy - but it's worth a thought.
Could you make foo
call the right doSomething
overload instead of just returning the value? That's the bit of code which knows what's being constructed - if you could pass it an object to call doSomething
on with the appropriate overload, you'd end up with the type-specific logic all in one place.
In Java 7 it's possible that invokedynamic will be useful in this sort of situation - certainly the dynamic
type in C# 4 would help - but I haven't looked into invokedynamic enough to say for sure.
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