2013-04-15 57 views
7

比方說,我有這樣的方法:泛型方法不帶參數

static class Example 
{ 
    public static <N extends Number> Number getOddBits(N type) 
    { 
     if (type instanceof Byte) return (byte)0xAA; 
     else if (type instanceof Short) return (short)0xAAAA; 
     else if (type instanceof Integer) return 0xAAAAAAAA; 
     else if (type instanceof Float) return Float.intBitsToFloat(0xAAAAAAAA); 
     else if (type instanceof Long) return 0xAAAAAAAAAAAAAAAAL; 
     else if (type instanceof Double) return Double.longBitsToDouble(0xAAAAAAAAAAAAAAAAL); 
     throw new IllegalArgumentException(); 
    } 
} 

該方法的實際細節是不是真的很重要。然而,調用這個方法,我們使用:

Example.<Float>getOddBits(0f); 

我的問題是,是否有可能寫出這樣的方法沒有常規參數。沒有超載,並最終沒有拳擊。

Example.<Byte>getOddBits(); 
+3

我想沒有,因爲刪除的,但你可以擺脫superflous實例參數,並使用一個類對象作爲參數:'getOddBits(類clazz中<擴展號碼?>)'。我不認爲你可以避開拳擊,因爲返回類型不足以創建不同的簽名,即'byte getOddBits()'和'int getOddBits()'可能是模糊的。 – Pyranja

+0

也可能有其他選項。你爲什麼需要這樣做?對於你的例子,基本上靜態值被返回,你可以使用枚舉。如果有更具體的東西,也可以有其他選擇。例如,如果要將數字轉換爲另一種形式,則可以使用toBytes和fromBytes方法創建轉換接口。然後有你需要的任何類來實現它。林不知道這是否有幫助,如果不是,你可以給出一個更具體的例子更接近你需要它做什麼? –

+0

@JohnKane這個例子是任意的,只是爲了演示如何以儘可能最小的方式通過參數指定子類的返回類型。我可能本來可以用舊的「foo-bar-baz」,但我認爲一個實際的例子會更適合。 – azz

回答

1

,以增強KennyTM的建議,你可以結合一類的說法與方法泛型返回專門類型:

@SuppressWarnings("unchecked") 
public static <N extends Number> N getOddBits(Class<N> cls) { 
    Number out; 
    if (cls == Byte.class) { 
     out = (byte)0xAA; 
    } else if (cls == Short.class) { 
     out = (short)0xAAAA; 
    } else if (cls == Integer.class) { 
     out = 0xAAAAAAAA; 
    } else if (cls == Float.class) { 
     out = Float.intBitsToFloat(0xAAAAAAAA); 
    } else if (cls == Long.class) { 
     out = 0xAAAAAAAAAAAAAAAAL; 
    } else if (cls == Double.class) { 
     out = Double.longBitsToDouble(0xAAAAAAAAAAAAAAAAL); 
    } else { 
     throw new IllegalArgumentException(); 
    } 
    return (N)out; 
} 

這將允許您指定以下內容,避免投上每次調用:

float result = Example.getOddBits(Float.class); 
+0

剛剛提交了一個編輯以支持原始值('cls == Integer。class || CLS == int.class')。從清晰的調用角度來看,這絕對是最佳的解決方案。 – azz

+0

(也就是'int i = Example.getOddBits(int.class);') – azz

7

如何只花.class

通過調用理想?

public static Number getOddBits(Class<? extends Number> cls) 
{ 
    if (cls == Byte.class) { 
     return (byte)0xAA; 
    } else if (cls == Short.class) { 
     return (short)0xAAAA; 
    } else if (cls == Integer.class) { 
     return 0xAAAAAAAA; 
    } else if (cls == Float.class) { 
     return Float.intBitsToFloat(0xAAAAAAAA); 
    } else if (cls == Long.class) { 
     return 0xAAAAAAAAAAAAAAAAL; 
    } else if (cls == Double.class) { 
     return Double.longBitsToDouble(0xAAAAAAAAAAAAAAAAL); 
    } 
    throw new IllegalArgumentException(); 
} 

... 

Example.getOddBits(Float.class); 
+0

這絕對有效。我真的想盡量推廣方法泛型,但我認爲擦除使用'Example'。 getOddBits()'不可能。 – azz

+0

可以這種方式結合了您的泛型方法簽名返回一個特殊類型:'公共靜態ñgetOddBits(類 CLS){' – seanhodges

+0

我已經擴大到如上一個新的答案我的意見。 – seanhodges

0

林不知道這是否會幫助你,但我已經在過去使用此爲反序列化並返回相應類型的對象。

public <T> T deserialize(String xml){ 
    T object=null; 
    ... 
    //pull type information from method param 
    ... 
    return object=(T)type.newInstance(); //helper to instantiate class 
} 

但是,我不完全確定你需要做什麼。一個更簡單,更簡潔的方法來實現這一點,可以爲你需要的給定類型創建一個Converter接口,並且可以使用它實現它所需的任何類。然後,您可以直接在Object上調用您需要的類型。例如:

inerface Convertor<T>{ 

    T convert(); 

    void set(T value); 

} 





class Something implements Converter<Long,ByteArray>{ 

    ... 

    public ByteArray convert(){...} 

    public void set(ByteArray value){...} 

}