Classworking 工具箱: 分析泛型数据结构
2010-03-18 00:00:00 来源:WEB开发网清单 6. 文件目录类
public abstract class Datalyze
{
private static void printDescription(TypeDescription basetype) {
ArrayList<TypeDescription> refs = new ArrayList<TypeDescription>();
HashSet<TypeDescription> dones = new HashSet<TypeDescription>();
refs.add(basetype);
for (int i = 0; i < refs.size(); i++) {
TypeDescription ref = refs.get(i);
System.out.println(ref + " fields:");
FieldDescription[] fields = ref.getFields();
for (int j = 0; j < fields.length; j++) {
FieldDescription field = fields[j];
TypeDescription ftype = field.getType();
System.out.println(" " + field.getName() + " of type " + ftype);
while (ftype.isArray()) {
ftype = ftype.getArrayItemType();
}
String fdtor = ftype.getDescriptor();
if (!dones.contains(ftype) && !ftype.isPrimitive() &&
ftype.getFields().length > 0 &&
!fdtor.startsWith("Ljava/lang") &&
!fdtor.startsWith("Lsun/")) {
refs.add(ftype);
dones.add(ftype);
}
}
}
}
public static void main(String[] args) {
BinaryClassLoader loader = new BinaryClassLoader();
loader.addPaths(System.getProperty("java.class.path"));
loader.addPaths(System.getProperty("sun.boot.class.path"));
TypeDirectory tdir = new TypeDirectory(loader);
TypeDescription desc =
tdir.getTypeInstance("Lcom/sosnoski/generics/PathDirectory;");
printDescription(desc);
}
}
com.sosnoski.generics.PathDirectory fields:
m_pathPairs of type
com.sosnoski.generics.PairCollection<java.lang.String,com.sosnoski.generics.DirInfo>
com.sosnoski.generics.PairCollection<java.lang.String,com.sosnoski.generics.DirInfo>
fields:
m_tValues of type java.util.ArrayList<java.lang.String>
m_uValues of type java.util.ArrayList<com.sosnoski.generics.DirInfo>
java.util.ArrayList<java.lang.String> fields:
serialVersionUID of type long
elementData of type java.lang.String[]
size of type int
java.util.ArrayList<com.sosnoski.generics.DirInfo> fields:
serialVersionUID of type long
elementData of type com.sosnoski.generics.DirInfo[]
size of type int
com.sosnoski.generics.DirInfo fields:
m_files of type java.util.List<com.sosnoski.generics.FileInfo>
m_directories of type java.util.List<com.sosnoski.generics.DirInfo>
m_lastModify of type java.util.Date
java.util.Date fields:
gcal of type sun.util.calendar.BaseCalendar
jcal of type sun.util.calendar.BaseCalendar
fastTime of type long
cdate of type sun.util.calendar.BaseCalendar$Date
defaultCenturyStart of type int
serialVersionUID of type long
wtb of type java.lang.String[]
ttb of type int[]
在清单 6 底部的输出中(为了格式化稍微重新调整了结构),可以看到类型替换代码的作用。类型替换的第一个实例在输出的第 4 和第 5 行,里面指定了 ArrayList 实例中值的类型。接下来的 ArrayList<String> 分析显示出它有一个 String[] 字段。这个输出也显示了数据结构分析的局限性:一旦遇到 DirInfo 类中的 List 字段,就没法进一步分解了,因为 java.util.List 是接口而不是实际的类 —— 而且只有接口的实现才有字段。当然,对本文提供的代码做些修改,也可以把同样的分析像用于字段一样用于方法,而且这种分析方法也能包含接口。
泛型结束语
到现在,已经看到了如何用 ASM 框架实现泛型数据结构分析,还有一个快速的示例,表现了这类分析的可能性和局限性。还有一些比较好的应用,通过在工具中整合泛型,在 Java 类之间和一些外部形式之间进行转换,从而提供详细的数据视图。例如,我正计划在我的 JiBX 数据绑定框架的新版本绑定生成器中,利用泛型提供的信息,在不需要用户的额外输入的情况下,填充结构的更多细节。
在三篇关于泛型的文章之后,我要换一个主题了!接下来的类处理工具包 系列中,我将介绍一个处理 Java 5 标注的工具。以前,我曾经介绍过在使用标注作为配置信息的时候出现的问题。这个工具通过允许在运行时覆盖标注数据,试图克服这些问题。覆盖标注的能力,能不能让它们用于更多类型的应用?请关注下个月的文章来找到答案。
本文示例源代码或素材下载
Tags:Classworking 工具箱 分析
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接