Динамическое явное приведение примитивных типов в Java с использованием отражения - PullRequest
0 голосов
/ 08 февраля 2011

У меня проблема с несоответствием типов аргументов, в то время как я пытаюсь установить значения, подобные представленным в обобщенном разделе.

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

   int intValue = 1;
   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;
  }

}

Дело в том, что я должен был ожидать явного приведения?

РЕДАКТИРОВАТЬ

Есть ли возможность предвидеть сужающие примитивные преобразования , которые могут иметь место, и выполнять их динамически, используя класс типов отражения и т.д.?

К вашему сведению:

Когда мы работаем с отражением примитивных типов, они больше не являются примитивными.

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

Один из способов добиться этого - изменить значение на строку, а затем с помощью конструктора строки в конкретном номере типа передать строку со значением.

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.

Ответы [ 3 ]

4 голосов
/ 08 февраля 2011
 /**
     * 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();

    }
4 голосов
/ 08 февраля 2011

Приведение long к int - это сужающее примитивное преобразование , которое может привести к потере точности, поэтому оно никогда не будет выполняться неявно.(За исключением константных выражений, но это не имеет значения в данной ситуации.)

1 голос
/ 08 февраля 2011

Если вы хотите передать приведение от вызывающего к классу, то перегрузите setIntValue():

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

но, поскольку вы скрываете сужение от своих абонентов, убедитесь, что это правильное решение во всех случаях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...