在Javassist中,是否保证退货订单?

时间:2014-04-04 21:51:02

标签: java reflection javassist

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

1 个答案:

答案 0 :(得分:2)

如果您查看CtClass的其中一个实现,例如CtClassType,您会看到getMethods()以这种方式实现:

public CtMethod[] getMethods() {
    HashMap h = new HashMap();
    getMethods0(h, this);
    return (CtMethod[])h.values().toArray(new CtMethod[h.size()]);
}

根据HashMap javadoc

  

此课程不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。

所以,你绝对不能保证你将获得这些方法的顺序。


对于字段,代码要复杂得多,但似乎原始类文件被读作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 SpecificationJava Language Specification时,我看不到生成的类中的字段顺序的引用; Java规范中的这句话甚至似乎表明字段顺序并不重要:

  

使用他们的方案,这里列出了Java编程语言支持的一些重要的二进制兼容更改:   [...]    重新排序现有类型声明中的字段,方法或构造函数。

所以我认为你也无法保证字段顺序。


我试图在我使用大量字段和方法创建的测试类上运行javassist.tools.Dump,似乎字段和方法是按源顺序打印的,但我仍然认为没有保证它。