Java Reflection:按声明顺序获取字段和方法

发布于 2024-10-17 08:04:54 字数 483 浏览 1 评论 0原文

有没有办法使用反射按声明顺序获取类声明的字段(和方法)?根据文档,getFields()getDeclaredFields()等返回的方法和字段的顺序是未定义的。

可以使用 Java 反射:类字段和方法的顺序是否标准化?

有没有更好的选择,即不必手动指定索引?

现在,在你问我需要这个做什么之前:我们有一个方法,它采用相当大的数据结构作为输入并对其执行冗长的计算。为了创建单元测试,我们创建了一个方法,该方法接受输入对象和输出实例,并创建 Java 源代码(设置输入、调用计算方法,然后断言正确的结果)作为输出。当字段按声明顺序写入时,此代码的可读性要高得多。

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.

Specifying something like an index would be possible using annotation as suggested in Java reflection: Is the order of class fields and methods standardized?

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

九公里浅绿 2024-10-24 08:04:54

在 jdk 6 中,反射字段实际上按照其声明顺序排列。在早期的jdk中并不是这样的。显然已经有足够多的人唠叨了。

虽然 javadoc 没有保证,但我仍然认为这个顺序是理所当然的,并且我假设这个顺序也将保留在未来的 jdks 中。

在您的应用程序中,就像在大多数应用程序中一样,对声明顺序的依赖主要是虚荣的 - 如果顺序搞砸了,您的应用程序不会失败,它只是变得有点难看。

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.

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.

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.

戴着白色围巾的女孩 2024-10-24 08:04:54

我将此作为一个孤立的问题,请查看

https://github.com/wmacevoy/kiss/blob/master/src/main/java/kiss/util/Reflect.java

和方法

公共静态方法[] getDeclaredMethodsInOrder(Class clazz)

它通过查看类的字节码来获取顺序。如果你只想使用库,那就是
kiss.util.Reflect.getDeclaredMethodsInOrder(Test.class)

I had this as an isolated problem, look at

https://github.com/wmacevoy/kiss/blob/master/src/main/java/kiss/util/Reflect.java

and the method

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)

放低过去 2024-10-24 08:04:54

不,通过反射是不可能的。但是,您可以使用 ProcessBuilder 和 javap 命令来解决它:

给定 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;
    }
}

命令 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();
...

No, not possible with reflection. You could however solve it using a ProcessBuilder and the javap command:

Given a 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:

...
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();
...
还如梦归 2024-10-24 08:04:54

不修改编译过程恐怕是不可能的。通常,该字段会以任何顺序写入类文件,并且有关声明顺序的信息会丢失。

您很可能可以使用注释处理器将订单写入辅助文件中。

这应该很容易。例如,查看 interfacegen 的示例,了解注释处理器如何工作。您可能希望将这些信息放在同一个文件中,但这要困难得多。

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 interfacegen for an example, how an annotation processor can work. You may want to put the information in the same file, but this is much harder.

恰似旧人归 2024-10-24 08:04:54

您可能会考虑将 Javadoc 与自定义 Doclet 一起使用,但这需要源代码可用。

仍然无法保证 API 中的顺序(方法fields,但是我见过的每个 javadoc 输出都以正确的顺序排列它们,所以我想 doclet 将它们放入申报单。

You may think about using Javadoc with a custom Doclet, but this requires the source to be available.

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.

天煞孤星 2024-10-24 08:04:54

您将无法从类文件中获取信息。正如亚当在回答其他问题时所说:

返回的数组中的元素未排序,也没有任何特定的顺序。

其中“无申报单”包括“无申报单”。

我曾经使用 Java 源文件解析器来获取代码生成器的输入数据。这样您就可以按声明顺序获得字段和方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文