开发者

Dynamic explicit cast of primitive types in Java using reflection

开发者 https://www.devze.com 2023-02-09 12:03 出处:网络
I\'ve a problem with argument type mismatch while I\'m try to set a values like it is presented using generics in hard section.

I've a problem with argument type mismatch while I'm try to set a values like it is presented using generics in hard section.

 public static void Main(String... args) {

   int intValue = 1;
开发者_Go百科   long longValue = 1l;
   Foo foo = new Foo();

  // Easy
  foo.setIntValue(intValue);
  foo.setLongValue(longValue);

  invokeSet(foo, "setIntValue",intValue);
  invokeSet(foo, "setLongValue",longValue);

  //Medium
  foo.setLongValue(intValue);   
  invokeSet(foo, "setLongValue",intValue);

  //Hard
  foo.setIntValue((int)longValue); //How to implement this in generic way ?
  invokeSet(foo, "setIntValue",longValue);
 }

class Foo {

 int intValue = 0
 long llongValue = 0;


  setIntValue(int i) {
    this.intValue = i;
  }

  setLongValue(long l) {
   this.longValue = l;
  }

}

The thing is that I had to anticipate the explicit cast ?

EDIT

Is there any possibility to anticipate the narrowing primitive conversions might take place and perform it in dynamic way using reflection types class etc.?

FYI:

When we are working with reflection on primitive types they are no longer primitive.

private static void invokeSet(Object bean, String methodName, Object value) throws Exception {
   Method m = retriveMethod(bean, methodName);
   m.invoke(bean,value); //More or less there is a type wrapper to change primitive to object class
}

EDIT2

One way to achieve this is to change the value to string and then using the string constructor in specific type number pass the string with value.

int intValue = 0;
long longValue = 0l;

Integer intObject = i;
Long longObject = l;

  intValue = (int)longValue;
  intOBject = new Integer(String.valueOf(longObject)); // intObject = (Integer) longValue; this is not allowed 

  intObject = longObject.intValue(); //Target to achieve with out writing bad code.


Casting long to int is a narrowing primitive conversion that may result in precision loss, therefore it will never be done implicitly. (With the exception of constant expressions, but this is irrelevant in this situation.)


 /**
     * Function that solve the problem with Numbers and narrowing primitive conversion. 
     * @param outputType - The type of output
     * @param value - Number object to be narrowed.
     */
    private static Number NarrovingNumberConversion(Class<? extends Number> outputType, Number value) {

        if(value == null) {
            return null;
        }
        if(Byte.class.equals(outputType)) {
           return value.byteValue(); 
        }
        if(Short.class.equals(outputType)) {
            return value.shortValue(); 
        }
        if(Integer.class.equals(outputType)) {
            return value.intValue(); 
        }
        if(Long.class.equals(outputType)) {
            return value.longValue(); 
        }
        if(Float.class.equals(outputType)) {
            return value.floatValue(); 
        }
        if(Double.class.equals(outputType)) {
            return value.doubleValue(); 
        }

        throw new TypeMismatchException();

    }


If you want to pass the cast from caller to the class, then overload setIntValue():

setIntValue(long l) {
  this.intValue = (int) l;
}

but, since you're hiding the narrowing from your callers, be sure this is the right thing to do in all cases.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号