# Android的泛型有多坑?
## 先來看看該問題的場景
將String轉換成具體對象時,需要進行的關鍵點就是獲取到對象的類型
``` java
// 這裏定義了一個泛型R,那運行時如何獲取到這個類型呢?
// 第一眼看上去,你會感覺,這不是很簡單嗎?
// 在onSuccess的方法中參數就能讀取到具體類型啊
// 問題的關鍵就是調用onSuccess前,如何創建R類型的參數
public interface Listener<R extends Result> {
void onSuccess(R result);
}
```
這個問題在jvm虛擬機上可以通過簡單的反射即可獲取到具體的泛型R類型,如下:
``` java
Type t = object.getClass().getGenericSuperclass();
Type claz = ((ParameterizedType) t).getActualTypeArguments()[0];
Class claz = object.getResultType();
```
但是上述代碼並不能很好的在Dalvik上運行,根本無法獲取到R的真實類型。
我們可以通過反射某個具體方法來獲取參數類型,間接的獲取到了R類型,如下:
``` java
Class claz = Default.class;
Method[] ms = object.getClass().getDeclaredMethods();
for (Method m : ms) {
if (!"methodName".equals(m.getName())) continue;
Class[] paramTypes = m.getParameterTypes();
if (paramTypes.length == 1 &&
Default.class.isAssignableFrom(paramTypes[0])) {
claz = paramTypes[0];
if(!paramTypes[0].isAssignableFrom(Default.class)) {
break;
}
}
}
```
當你真實的運行了上述代碼後,你會發現在java虛擬機看來,不同的參數類型,不同的返回類型,都是函數重載。只用完全相同的參數類型和返回類型才能算是重寫,也就是函數名與函數簽名必須完全一致。java字節碼的規則遠比IDE的規則要複雜。
## 逼格知識點
> java函數只有返回類型不同,是重載還是重寫?
普通程序員會說IDE編譯報錯,並能夠區分出重寫與重載,但是解析不具有深度
請一定記住以下有深度的解析
1. IDE不一定完全報錯
2. jdk6以下是可以構成重載成功的,主要是參數爲泛型時,表達了兩個不同的具體類型時,能繞過編譯器的檢查
3. jdk7及以上是編譯不通過的,但是已經編譯成功的字節碼中,仍然會因返回類型的變化構成重載函數。
4. 在jni開發時應該要注意這種特殊的重載