("=") 说明实际类型由当前类的类型参数 (java.util.List) 提供,visitClassType ("com/sosnoski/generics/FileInfo") 说明实际类型以 com.sosnoski.generics.FileInfo 为基础。最 终,对 visitEnd() 的第一个调用关闭了打开的 FileInfo 类签名,第二个调用关闭了打开的 List 类签 名。
通过观察访问器方法调用序列,您或许已经猜到,其中部分调用有效地为嵌入的类型签名组 件打开了一个新的上下文。SignatureVisitor 接口中返回 SignatureVisitor 实例的方法均有此作用。 方法调用所返回的接口实例(可能与被调用的实例相同,也可能不同,清单 5 代码中就是相同的)随后 用于处理嵌入的类型签名。可很容易地对 清单 5 所示代码作出修改,以缩进格式展示子签名嵌套,本文 提供的下载文件中也包含更改后的代码。这里不准备给出详细的代码,仅介绍输出结果。清单 7 给出了 在 清单 2 的 PairCollection 参数化类上运行此缩进版代码时所生成的输出结果(部分):
清 单 7. PairCollection 代码和签名分析
public class PairCollection<T,U> implements Iterable<T>
{
/** Collection with first component values. */
private final ArrayList<T> m_tValues;
/** Collection with second component values. */
private final ArrayList<U> m_uValues;
...
public void add(T t, U u) {
m_tValues.add(t);
m_uValues.add(u);
}
public U get(T t) {
int index = m_tValues.indexOf(t);
if (index >= 0) {
return m_uValues.get(index);
} else {
return null;
}
}
...
}
Class com/sosnoski/generics/PairCollection signature:
<T:Ljava/lang/Object;U:Ljava/lang/Object;>Ljava/lang/Object;Ljava/lang/Iterable<TT; >;
visitFormalTypeParameter(T)
visitClassBound()
visitClassType (java/lang/Object)
visitEnd()
visitFormalTypeParameter(U)
visitClassBound()
visitClassType(java/lang/Object)
visitEnd()
visitSuperclass()
visitClassType(java/lang/Object)
visitEnd()
visitInterface()
visitClassType(java/lang/Iterable)
visitTypeArgument(=)
visitTypeVariable(T)
visitEnd()
Field m_tValues signature:
Ljava/util/ArrayList<TT;>;
visitClassType(java/util/ArrayList)
visitTypeArgument(=)
visitTypeVariable(T)
visitEnd()
Field m_uValues signature:
Ljava/util/ArrayList<TU;>;
visitClassType (java/util/ArrayList)
visitTypeArgument(=)
visitTypeVariable(U)
visitEnd()
Method add() signature:
(TT;TU;)V
visitParameterType()
visitTypeVariable(T)
visitParameterType()
visitTypeVariable(U)
visitReturnType()
visitBaseType(V)
Method get() signature:
(TT;) TU;
visitParameterType()
visitTypeVariable(T)
visitReturnType()
visitTypeVariable(U)
清单 7 输出显示了嵌套类型定义在被解析的签名中的使用方 法。在处理类签名时,嵌套可能深达两层 —— 类签名包含一个类必须实现的接口签名,接口 签名又包含一个类型参数签名(也就是本例中的类型变量 “T”)。
进一步了解 ASM 泛型
本文介绍了一些基础知识,包括泛型信息在二进制类表示中的存储方式及使用 ASM 访问泛 |