今天在做解析网络请求后得到的数据的转化的时候用到了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();
}
运行结果:
我们可以看到,clazz.getGenericInterfaces()与clazz.getInterfaces()并没有任何差异。因为 并没有:“实现的接口的Type”
接下来看另一段代码,我们对Eat接口改造一下,增加参数化类型
private class Food{
String foodName;
}
private interface Eat<T>{
void eat(T things);
}
private interface Run{
void run();
}
private class Dog implements Eat<Food>,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();
}
运行结果:
可以看到: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
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
小的才疏学浅,难免有些地方会有错误,欢迎指正。