java: How can I do dynamic casting of a variable from one type to another?

ufk picture ufk · Jan 24, 2010 · Viewed 205.7k times · Source

I would like to do dynamic casting for a Java variable, the casting type is stored in a different variable.

This is the regular casting:

 String a = (String) 5;

This is what I want:

 String theType = 'String';
 String a = (theType) 5;

Is this possible, and if so how? Thanks!

Update

I'm trying to populate a class with a HashMap that I received.

This is the constructor:

public ConnectParams(HashMap<String,Object> obj) {

    for (Map.Entry<String, Object> entry : obj.entrySet()) {
        try {
            Field f =  this.getClass().getField(entry.getKey());                
            f.set(this, entry.getValue()); /* <= CASTING PROBLEM */
        } catch (NoSuchFieldException ex) {
            log.error("did not find field '" + entry.getKey() + '"');
        } catch (IllegalAccessException ex) {
            log.error(ex.getMessage());         
        }
    }

}

The problem here is that some of the class' variables are of type Double, and if the number 3 is received it sees it as Integer and I have type problem.

Answer

user85421 picture user85421 · Jan 24, 2010

Yes it is possible using Reflection

Object something = "something";
String theType = "java.lang.String";
Class<?> theClass = Class.forName(theType);
Object obj = theClass.cast(something);

but that doesn't make much sense since the resulting object must be saved in a variable of Object type. If you need the variable be of a given class, you can just cast to that class.

If you want to obtain a given class, Number for example:

Object something = new Integer(123);
String theType = "java.lang.Number";
Class<? extends Number> theClass = Class.forName(theType).asSubclass(Number.class);
Number obj = theClass.cast(something);

but there is still no point doing it so, you could just cast to Number.

Casting of an object does NOT change anything; it is just the way the compiler treats it.
The only reason to do something like that is to check if the object is an instance of the given class or of any subclass of it, but that would be better done using instanceof or Class.isInstance().

Update

according your last update the real problem is that you have an Integer in your HashMap that should be assigned to a Double. What you can do in this case, is check the type of the field and use the xxxValue() methods of Number

...
Field f =  this.getClass().getField(entry.getKey());
Object value = entry.getValue();
if (Integer.class.isAssignableFrom(f.getType())) {
    value = Integer.valueOf(((Number) entry.getValue()).intValue());
} else if (Double.class.isAssignableFrom(f.getType())) {
    value = Double.valueOf(((Number) entry.getValue()).doubleValue());
} // other cases as needed (Long, Float, ...)
f.set(this, value);
...

(not sure if I like the idea of having the wrong type in the Map)