2011-02-08 43 views
0

我有一個參數類型不匹配的問題,而我嘗試設置一個值,如使用硬節中的泛型所示。使用反射動態顯式轉換Java中的原始類型

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; 
    } 

}

的事情是,我必須預見到明確的投?

編輯

是否有可能預見到基本收縮轉換可能發生,使用反射型類等動態的方式進行呢?

FYI:

當我們對原始反射類型的工作,他們不再是原始的。

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. 
+0

你是什麼意思的「以通用的方式」?如果你沒有顯式的強制轉換,編譯器會正確地抱怨,因爲你試圖強制一個'long'變成'int'。你想要它做什麼? –

+0

什麼是「invokeSet」?使用反射設置bean上的值的函數?你可以在你的問題更具體嗎? –

+0

@Oli使用反射。我的錯誤。 @Luciano,是的,它是一個使用反射將值設置爲bean的函數。 –

回答

3
/** 
    * 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

鑄造longintnarrowing primitive conversion可能導致精度損失,因此它永遠不會被隱式進行。 (使用常量表達式的例外,但是這是在這種情況下不相關)

+0

這是真的,從來沒有那麼少,當這種情況發生在代碼中時,它不應該用異常完成,但使用縮小原始轉換轉換數字並繼續。 –

+1

@Vash真的取決於應用程序。誠然,Java不會在溢出或下溢時拋出異常,但您可能希望應用程序這樣做。例如,我不會相信一個財務應用程序不會在溢出時拋出異常。 – biziclop

+0

Totaly的權利,我想eddit我的評論,但是要遲到,而不是通常寫我應該在我的代碼中寫這應該這樣處理。 –

1

如果你想從呼叫者投傳遞給類,然後重載setIntValue()

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

但是,既然你」重新隱藏你的呼叫者的縮小範圍,確保在所有情況下這都是正確的。

+0

@Yishai - 感謝您的編輯。今天早上沒有足夠的咖啡:-) –

+1

我不能這樣做,因爲我不知道這個代碼將被用於哪種方法。但是,謝謝你的觀點。 –