Java 反射:按声明顺序获取字段和方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5001172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Reflection: Getting fields and methods in declaration order
提问by Axel
Is there any way to get a classes declared fields (and methods) in the order of declaration using reflection? According to the documentation, the ordering of Methods and Fields returned by getFields()
, getDeclaredFields()
, etc. is undefined.
有没有办法按照使用反射的声明顺序获取类声明的字段(和方法)?根据该文件,方法和字段的顺序返回的getFields()
,getDeclaredFields()
等不确定。
Specifying something like an index would be possible using annotation as suggested in Java reflection: Is the order of class fields and methods standardized?
可以使用Java 反射中建议的注释来指定诸如索引之类的东西:类字段和方法的顺序是否标准化?
Are there any better options, i.e. not having to specify the index manually?
有没有更好的选择,即不必手动指定索引?
Now before you ask what I need this for: we have a method that takes a quite big data structure as input and performs a lengthy calculation on it. To create unit tests, we made a method that takes an input object and an output instance and creates the Java source code (setting up input, invoking the calculation method, and asserting the correct results afterwards) as output. This code is much more readable when fields are written in declaration order.
现在,在你问我需要它做什么之前:我们有一种方法,它以相当大的数据结构作为输入并对其执行冗长的计算。为了创建单元测试,我们创建了一个方法,它接受一个输入对象和一个输出实例,并创建 Java 源代码(设置输入,调用计算方法,然后断言正确的结果)作为输出。当字段按声明顺序编写时,此代码更具可读性。
采纳答案by irreputable
With jdk 6, the reflected fields are in deed in their declaration order. In early jdk that wasn't the case. Apparently enough people have nagged.
使用 jdk 6,反射的字段确实按其声明顺序排列。在早期的 jdk 中,情况并非如此。显然,已经有足够多的人唠叨了。
Although not guaranteed by javadoc, I would still take this order as granted, and I assume the order will be kept in future jdks too.
虽然 javadoc 没有保证,但我仍然认为这个顺序是理所当然的,我认为这个顺序也会保留在未来的 jdks 中。
In your app, like in most apps, the dependency on the declaration order is mostly vanity - your app won't fail if the order screws up, it just become a little uglier.
在您的应用程序中,就像在大多数应用程序中一样,对声明顺序的依赖主要是虚荣的——如果顺序出错,您的应用程序不会失败,只是变得更丑一点。
回答by aioobe
No, not possible with reflection. You could however solve it using a ProcessBuilder
and the javap
command:
不,用反射是不可能的。但是,您可以使用 aProcessBuilder
和javap
命令解决它:
Given a Test.java
:
给定一个Test.java
:
public abstract class Test {
public void method1() {
}
public void method2() {
}
public static void main(String[] args) {
}
public String method3() {
return "hello";
}
abstract void method4();
final int method5() {
return 0;
}
}
The command javap Test
prints:
该命令javap Test
打印:
...
public Test();
public void method1();
public void method2();
public static void main(java.lang.String[]);
public java.lang.String method3();
abstract void method4();
final int method5();
...
回答by Warren MacEvoy
I had this as an isolated problem, look at
我有这个作为一个孤立的问题,看看
https://github.com/wmacevoy/kiss/blob/master/src/main/java/kiss/util/Reflect.java
https://github.com/wmacevoy/kiss/blob/master/src/main/java/kiss/util/Reflect.java
and the method
和方法
public static Method[] getDeclaredMethodsInOrder(Class clazz)
public static Method[] getDeclaredMethodsInOrder(Class clazz)
It gets the order by looking at the bytecode of the class. If you just want to use the libray, is would be
kiss.util.Reflect.getDeclaredMethodsInOrder(Test.class)
它通过查看类的字节码来获取顺序。如果你只想使用库,那就是
kiss.util.Reflect.getDeclaredMethodsInOrder(Test.class)
回答by maaartinus
I'm afraid it's impossible without modifying the compilation process. Normally, the field get written into the classfile in any order and the information about the declaration order gets lost.
不修改编译过程恐怕是不行的。通常,该字段以任何顺序写入类文件,并且有关声明顺序的信息会丢失。
Most probably you could use an annotation processor to write the order in an auxiliary file.
很可能您可以使用注释处理器将订单写入辅助文件中。
It should be quite easy. Look e.g. at interfacegenfor an example, how an annotation processor can work. You may want to put the information in the same file, but this is much harder.
这应该很容易。以interfacegen为例,注解处理器如何工作。您可能希望将信息放在同一个文件中,但这要困难得多。
回答by Pa?lo Ebermann
You may think about using Javadoc with a custom Doclet, but this requires the source to be available.
您可能会考虑将 Javadoc 与自定义 Doclet 一起使用,但这需要提供可用的源代码。
There still is no guarantee about the order in the API (methods, fields, but every javadoc output I've ever seen has them in the right order, so I suppose the doclets get them in declaration order.
仍然无法保证 API 中的顺序(methods、fields,但我见过的每个 javadoc 输出都以正确的顺序排列它们,所以我想 doclet 以声明顺序获取它们。
回答by Andreas Dolk
You won't be able to get the information from the class file. As Adam said in an answer to the refrenced other question:
您将无法从类文件中获取信息。正如亚当在回答另一个问题时所说:
The elements in the array returned are not sorted and are not in any particular order.
返回的数组中的元素没有排序,也没有任何特定的顺序。
And "no order" includes "no declaration order".
而“无订单”包括“无申报订单”。
I once used a Java source file parser to get input data for code generators. And this way you'll have fields and methods in declaration order.
我曾经使用 Java 源文件解析器来获取代码生成器的输入数据。通过这种方式,您将拥有按声明顺序排列的字段和方法。