java getgenericinterfaces_Java反射中getGenericInterfaces和getInterfaces的解读

今天在做解析网络请求后得到的数据的转化的时候用到了getGenericInterfaces这个方法,顺便也了解了下和他长得差不多的getInterfaces方法。

官方文档解释

getGenericInterfaces:

Returns the {@code Type}s representing the interfaces directly implemented by the class or interface represented by this object.释意:返回表示由此对象表示的类或接口直接实现的接口的{@code Type}。

getInterfaces:

Determines the interfaces implemented by the class or interface represented by this object. 释意:返回由此对象表示的类或接口实现的接口。

从解释上面来看出来了,差异在于“接口实现的接口的Type”,接下来用具体示例来解释区别

private class Food{

String foodName;

}

private interface Eat{

void eat(String things);

}

private interface Run{

void run();

}

private class Dog implements Eat,Run{

@Override

public void run() { }

@Override

public void eat(String things) { }

}

private void main() {

Class> clazz = Dog.class;

Type[] genericInterfaces = clazz.getGenericInterfaces();

Class>[] interfaces = clazz.getInterfaces();

}

运行结果:

78e091957bb9707461c40b4c8fa1f3a4.png

我们可以看到,clazz.getGenericInterfaces()与clazz.getInterfaces()并没有任何差异。因为 并没有:“实现的接口的Type”

接下来看另一段代码,我们对Eat接口改造一下,增加参数化类型

private class Food{

String foodName;

}

private interface Eat{

void eat(T things);

}

private interface Run{

void run();

}

private class Dog implements Eat,Run{

@Override

public void run() { }

@Override

public void eat(Food things) { }

}

private void main() {

Class> clazz = Dog.class;

Type[] genericInterfaces = clazz.getGenericInterfaces();

Class>[] interfaces = clazz.getInterfaces();

}

运行结果:

7e099e618060fe3515652bc6962013c0.png

可以看到:clazz.getGenericInterfaces();所生成的数组里有一个接口类型为:ParameterizedType 而ParameterizedType extends Type 而ParameterizedType 和 Type 有什么区别呢?

Type代表 包括原始类型,参数化类型、数组类型、类型变量和原始类型,而ParameterizedType只代表参数化类型 官方文档:

ParameterizedType represents a parameterized type such as Collection

译:ParameterizedType表示参数化类型,例如 Collection ParameterizedType相对于Type新增了三个接口方法:

Type[] getActualTypeArguments(); //返回参数化类型的实际类型的数组 例如:Food那么将返回 [Fruit,Vegetable]这两个类型的数组 下面两种方法就不用多说了,从字面意思就能看出来。

Type getRawType();

Type getOwnerType();

回到上面,在看getGenericInterfaces()的内部实之前现,我们先看看getInterfaces()的内部实现

public Class>[] getInterfaces() {

if (isArray()) {

return new Class>[] { Cloneable.class, Serializable.class };

}

final Class>[] ifaces = getInterfacesInternal();

if (ifaces == null) {

return EmptyArray.CLASS;

}

return ifaces;

}

@FastNative

private native Class>[] getInterfacesInternal();

可以看到,getInterfaces源码逻辑比较简单先判断传入的是不是一个class 数组,我们这里先对单个class进行讨论,暂且不管,后面使用了native方法getInterfacesInternal

再看getGenericInterfaces()的内部实现

public Type[] getGenericInterfaces() {

Type[] result;

synchronized (Caches.genericInterfaces) {

result = Caches.genericInterfaces.get(this);

if (result == null) {

String annotationSignature = getSignatureAttribute();

if (annotationSignature == null) {

result = getInterfaces();

} else {

GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());

parser.parseForClass(this, annotationSignature);

result = Types.getTypeArray(parser.interfaceTypes, false);

}

Caches.genericInterfaces.put(this, result);

}

}

return (result.length == 0) ? result : result.clone();

}`

内部实现完全和getInterfaces()不太一样 逻辑是:

1、从缓存中取genericInterfaces

2、没有再利用 getSignatureAttribute(),先不管getSignatureAttribute具体做了什么,从字面意思上看是获取了相关属性

3、getSignatureAttribute值为null则执行 getInterfaces,否则继续获取 4、缓存数据

其实这里我们已经能明白getInterfaces和getGenericInterfaces的差异性了,主要在getSignatureAttribute()这里,接下来继续对getSignatureAttribute()进行分析

getSignatureAttribute()的内部实现为:

private String getSignatureAttribute() {

String[] annotation = getSignatureAnnotation();

if (annotation == null) {

return null;

}

StringBuilder result = new StringBuilder();

for (String s : annotation) {

result.append(s);

}

return result.toString();

}

最主要看getSignatureAnnotation(),这又是一个native方法,这个之后再进行详细讲解。

对上面的内容进行一个总结:

getInterfaces:主要是 获取由此对象表示的类或接口实现的接口

getGenericInterfaces: 主要是 获取由此对象表示的类或接口直接实现的接口的Type。

区别在于getGenericInterfaces可以返回其参数化类型,例如: Collection、 List中的String和Coupon

小的才疏学浅,难免有些地方会有错误,欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值