1

I am building something like a data flow graph, with nodes and connections that pass data between them. The base class in this case is ValueTarget<T>, which has a previous and a next target to pass data back and forth. Other classes extend this class to provide sources for the data, merge data (e.g. a multiplication) etc.

Now, I wanted to write a data source that takes its value from any given method. It takes a java.lang.reflect.Method instance (and the Object and parameters to invoke it) and uses this to set the data:

@Override
public T getValue() {

    if (valueCalculator != null) {
        try {
            Object result = valueCalculator.invoke(sourceObject);
            T typedResult = (T)(result);
            return typedResult;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    return super.getValue();
}

Now, I have tried this with the public int getLength() Method of another object. However, in the graph, I need to map this method to a float result. The given typecast doesn't throw an Exception, but when reading the last ValueTarget<Float>'s value and using its result as a float parameter to another method, the program crashes, stating that "java.lang.Integer cannot be cast to java.lang.Float".

Now, I am aware that Integer and Float are boxed and therefore cannot be cast into each other's type. However, as the types are all handled using the generics, I cannot unbox to a specific type.

Is there any way to perform a generic unboxing in order to be able to cast boxed values into the according value-types?

Jay
  • 237
  • 2
  • 14

2 Answers2

2

How about using Number.floatValue()?

Object result = valueCalculator.invoke(sourceObject);
Float f = ((Number)result).floatValue();
System.out.println(f);

... or however you want to use it.

Here I'm assuming the return type is one of these - BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, and Short (which are all subclasses of Number).

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
  • If result can't be typecast to Number then again it will throw type cast error. – Vijay Sep 17 '13 at 14:12
  • @Vijay If it can't be typecast to `Number`, I'm not sure what the behaviour should be then. There is no generic method that allows for other conversions, thus no generic solution. – Bernhard Barker Sep 17 '13 at 14:17
  • 1
    I'm not sure whether or not this is how you meant it, but by simply using as the smallest common denominator to pass numbers through the graph instead of using particular types such as Float, I could bypass the whole problem. Thank you. – Jay Sep 17 '13 at 14:33
1

You can use Apache CommonBeanUtils library to convert types at runtime.

org.apache.commons.beanutils.ConvertUtils.convert(Object value, Class targetType)

so you change the typecaste code

  T typedResult = (T)(result);

replace with this

 T typedResult = (T)org.apache.commons.beanutils.ConvertUtils.convert(result, T.getClass());
Vijay
  • 1,024
  • 6
  • 18