Android下的Java之interface接口泛型 动态获取泛型的类型
# Android的泛型有多坑?
## 先来看看该问题的场景
将String转换成具体对象时,需要进行的关键点就是获取到对象的类型
``` java
// 这里定义了一个泛型R,那运行时如何获取到这个类型呢?
// 第一眼看上去,你会感觉,这不是很简单吗?
// 在onSuccess的方法中参数就能读取到具体类型啊
// 问题的关键就是调用onSuccess前,如何创建R类型的参数
public interface Listener
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开发时应该要注意这种特殊的重载
更多相关文章
- android 6.0获取mac 地址都是02:00:00:00:00:00 的问题
- Android动态获取资源ID并使用javabean进行赋值
- Android触摸滑动全解(三)——View坐标体系详解
- 如何获取和安装Android(安卓)L开发者预览版
- Android(安卓)多线程:使用Thread和Handler (从网络上获取图片)
- 通过View.post()获取View的宽高引发的两个问题:1post的Runnable何
- Android中so使用知识和问题总结以及插件开发过程中加载so的方案
- android多线程详解之Handler
- 微信授权APP第三方登陆(Android)