Classworking 工具箱: 分析泛型数据结构
2010-03-18 00:00:00 来源:WEB开发网清单 2 的代码使用内部的 PrimitiveTypeDescription 和 ArrayTypeDescription 类直接处理原生类型和数组类型。原生类型在创建的时候就被添加到实际的目录(m_typeMap 哈希映射把类型名称或字段签名与对应的类型描述关联起来),而数组类型则在被看到的时候添加到目录中。getTypeInstance() 方法处理新的数组类型的添加,递归地调用本身来得到数组的项目类型的类型描述。实际的 Java 类的类型则通过把二进制类表示传递给 SimpleClassDescription 构造函数而生成。
getSignatureInstance() 方法在结构上与 getTypeInstance() 方法很类似,但是如果在前面没有遇到使用某个泛型类的参数类型的相同组合,它还需要处理到泛型类的类型替换。马上我就要编写实际执行这个任务的代码,以及相关的 getMappedSignatureInstance() 代码。首先,我要处理的代码负责构建不带指定参数类型的类的描述。
用 ASM 构建类描述
清单 3 显示了简单类描述的实际构造,所谓简单类,我指的是非泛型类或者不带指定参数类型的泛型类。这个类的全部工作都发生在构造函数中,构造函数首先把类的新实例添加到类型目录(以处理递归,就像在 前一节 中讨论的),然后用 ASM 处理实际的二进制类表示,构建一组字段描述。
清单 3. SimpleClassDescription 类
public class SimpleClassDescription extends TypeDescription
{
private final String m_name;
private final FieldDescription[] m_fields;
public SimpleClassDescription(String dtor, byte[] byts, TypeDirectory dir) {
super(dtor);
m_name = BinaryClassLoader.nameFromDescriptor(dtor);
dir.addType(this);
DescriptionBuilderVisitor vtor = new DescriptionBuilderVisitor(dir);
ClassReader creader = new ClassReader(byts);
creader.accept(vtor, true);
m_fields = vtor.getFields();
}
public FieldDescription[] getFields() {
return m_fields;
}
public String toString() {
return m_name;
}
/**
* Visitor for generating the description information for a simple class (a
* non-generic class, or a generic class used without type substitution).
* If the class is generic, the bounds information from the signature is
* substituted for the type parameters.
*/
public class DescriptionBuilderVisitor extends EmptyVisitor
{
private final TypeDirectory m_typeDirectory;
private HashMap<String,TypeDescription> m_typeMap;
private ArrayList<FieldDescription> m_fields;
private DescriptionBuilderVisitor(TypeDirectory dir) {
m_typeDirectory = dir;
m_fields = new ArrayList<FieldDescription>();
}
public void visit(int version, int access, String name, String sig,
String sname, String[] inames) {
if (sig != null) {
m_typeMap = new HashMap<String,TypeDescription>();
new SignatureReader(sig).accept(new ClassSignatureVisitor());
}
}
public FieldVisitor visitField(int access, String name, String desc,
String sig, Object value) {
TypeDescription type;
if (sig == null) {
type = m_typeDirectory.getTypeInstance(desc);
} else {
type = m_typeDirectory.getMappedSignatureInstance(sig, m_typeMap);
}
m_fields.add(new FieldDescription(name, sig, type));
return super.visitField(access, name, desc, sig, value);
}
private FieldDescription[] getFields() {
return m_fields.toArray(new FieldDescription[m_fields.size()]);
}
private class ClassSignatureVisitor extends EmptySignatureVisitor
{
private String m_lastName;
private boolean m_isBounded;
public void visitFormalTypeParameter(String name) {
m_typeMap.put(name,
m_typeDirectory.getTypeInstance("Ljava/lang/Object;"));
m_lastName = name;
}
public SignatureVisitor visitClassBound() {
return new EmptySignatureVisitor() {
public void visitClassType(String name) {
m_typeMap.put(m_lastName,
m_typeDirectory.getTypeInstance("L" + name + ';'));
m_isBounded = true;
}
};
}
public SignatureVisitor visitInterfaceBound() {
return new EmptySignatureVisitor() {
public void visitClassType(String name) {
if (!m_isBounded) {
m_typeMap.put(m_lastName,
m_typeDirectory.getTypeInstance(name));
}
}
};
}
}
}
}
Tags:Classworking 工具箱 分析
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接