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

# 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开发时应该要注意这种特殊的重载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值