Javassist CtClass
有一些方法,例如getFields()
和getMethods()
。我想知道这些方法是否能为他们的订购提供任何保证。
具体来说,我想知道在类上使用getFields()
是否会生成CtFields
数组,其中数组中的第一个字段是文件中声明的第一个字段,因此向前。那么,这个订单有保证吗?如果没有,有什么可以提供这种保证吗? javadocs没有提供有关此事的信息。我尝试了带有顺序的注释(例如@X(1) private int first;
),但如果我能在不需要注释的情况下反映这类内容,那么它会更容易吗?
如果还不清楚,我会喜欢这样的话:
public class Class {
public int x;
public float y;
public Object z;
}
生成一个CtFields
数组,专门且一致地排序x, y, z
。
答案 0 :(得分:2)
如果您查看CtClass
的其中一个实现,例如CtClassType
,您会看到getMethods()
以这种方式实现:
public CtMethod[] getMethods() {
HashMap h = new HashMap();
getMethods0(h, this);
return (CtMethod[])h.values().toArray(new CtMethod[h.size()]);
}
此课程不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。
所以,你绝对不能保证你将获得这些方法的顺序。
对于字段,代码要复杂得多,但似乎原始类文件被读作InputStream
:
DataInputStream in = new DataInputStream(
new FileInputStream(args[0]));
ClassFile w = new ClassFile(in);
这些字段是在从此流中读取时创建的:
fields = new ArrayList();
for (i = 0; i < n; ++i)
addField2(new FieldInfo(cp, in));
因此,字段按照它们在类文件中的顺序创建。
但是,在阅读JVM Specification和Java Language Specification时,我看不到生成的类中的字段顺序的引用; Java规范中的这句话甚至似乎表明字段顺序并不重要:
使用他们的方案,这里列出了Java编程语言支持的一些重要的二进制兼容更改: [...] 重新排序现有类型声明中的字段,方法或构造函数。
所以我认为你也无法保证字段顺序。
我试图在我使用大量字段和方法创建的测试类上运行javassist.tools.Dump
,似乎字段和方法是按源顺序打印的,但我仍然认为没有保证它。