Android下的Java之interface接口泛型 动态获取泛型的类型

2018-03-01 11:11:29来源:https://www.jianshu.com/p/4d4e6be71019作者:ReadyShow人点击

分享


Android的泛型有多坑?
先来看看该问题的场景

将String转换成具体对象时,需要进行的关键点就是获取到对象的类型


// 这里定义了一个泛型R,那运行时如何获取到这个类型呢?
// 第一眼看上去,你会感觉,这不是很简单吗?
// 在onSuccess的方法中参数就能读取到具体类型啊
// 问题的关键就是调用onSuccess前,如何创建R类型的参数
public interface Listener<R extends Result> {
void onSuccess(R result);
}

这个问题在jvm虚拟机上可以通过简单的反射即可获取到具体的泛型R类型,如下:


Type t = object.getClass().getGenericSuperclass();
Type claz = ((ParameterizedType) t).getActualTypeArguments()[0];
Class claz = object.getResultType();

但是上述代码并不能很好的在Dalvik上运行,根本无法获取到R的真实类型。
我们可以通过反射某个具体方法来获取参数类型,间接的获取到了R类型,如下:


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编译报错,并能够区分出重写与重载,但是解析不具有深度


请一定记住以下有深度的解析


IDE不一定完全报错
jdk6以下是可以构成重载成功的,主要是参数为泛型时,表达了两个不同的具体类型时,能绕过编译器的检查
jdk7及以上是编译不通过的,但是已经编译成功的字节码中,仍然会因返回类型的变化构成重载函数。
在jni开发时应该要注意这种特殊的重载







最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台