有保证的方法可以在运行时获取成员字段的源顺序吗?

2024-03-26

我正在寻找一种按源顺序检索(在运行时)类的字段的方法,以便我可以执行自己的“初始化处理”,该处理基于声明的顺序。我知道 Javadoc 用于Class.getDeclaredFields()明确指出不保证订单。

SO 上的一些答案指向Javassist但我找不到任何证据表明javassist在没有行号信息的情况下有任何此类保证。

然而 Java 编译器使用了这种“源代码顺序”,因为此代码无法编译:

private int a = 10 * b;
private int b = 5;

显然,价值b目前尚不清楚a正在宣布。

这个初始化顺序也必须出现在字节码中,因为在运行时初始化必须以相同的顺序发生(当然,这只是这些边缘情况的要求:-(但这让我认为自然的事情是存储里面的源顺序.class file.

问题:

  1. JVM/字节代码如何按照声明的顺序初始化成员字段,这些信息是否可以用于重建字段的源顺序?

  2. 有没有其他有保证的方法可以实现同样的目标。像Javassist这样的第三方工具是可以的,但它必须是“有保证的”或者至少是“在特定条件下有保证”。

  3. 是否有任何特定的 Java 实现可以保证顺序Class.getDeclaredFields()(也许在特定条件下(哪些条件))?

供您参考,我需要源顺序来重建顺序很重要的遗留语言的行为。我不喜欢明确添加订单,例如通过添加数组或注释,因为我想保持源代码尽可能可读。

- 编辑 - 一个重要的注意事项可能是我需要“遍历”的字段都将被注释,例如@MyComplexType(len = 4)。父类将需要此元信息来构造一种内存映射。然而,我不想让这个注释与订购信息混淆,因为我发现这会妨碍可读性和可维护性。


关于你的第二个问题和第三个问题,只能使用一种肮脏的黑客方法按顺序检索字段:

在字节码中,类文件的字段和方法都不是按顺序存储的。我不知道why情况确实如此(尽管我制作了自己的 JVM 编译器),但我相信 Java 编译器只是决定这样做。Class.getDeclaredFields按照从字节码读取字段的顺序返回字段,这就是为什么它声明不保证顺序。

如果您仍然想让它们按顺序排列,我会尝试以下操作:您使用字节码解析器库(例如 Javassist 或 ASM)来读取类文件,并跳过除构造函数(以及static {}如果您还想对静态字段进行排序)。一旦你遇到一个PUTFIELD or PUTSTATIC指令的owner是您正在检查的类,您可以通过字节码中存储的调试信息获取可用的当前行,并使用它对字段进行排序。这种技术的问题是效率低下,而且它依赖于行号属性,而这些属性并不总是存在于类文件中。此外,你只会发现PUT*显式初始化字段的说明,默认字段,例如

protected int modifiers;

未由编译器初始化,因此字节码中没有可用的指令和行号信息。在这种情况下,或者当一般没有 LineNumber 属性时,您很不幸地运气不好。此时,我能想到的唯一解决方案就是阅读该类的实际源代码。

根据您尝试检查的类,您可能无法获取该类的实际字节码,但这本身就是一个问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有保证的方法可以在运行时获取成员字段的源顺序吗? 的相关文章

随机推荐

  • Export-CSV 仅获取“长度”

    当我尝试导出到 CSV 列表时 我只得到 长度 的所有数字 Count属性 直到到达分割点 然后将 CSV 数组分割到一个新文件 并使用从此时开始使用的新名称 可能是什么问题 RootFolder Get Content c DRIVERS
  • `agrep(...,fixed=F)` 的困难

    In agrep grep模糊匹配 它提到我可以设置参数fixed FALSE让我的模式被解释为正则表达式 但是 我无法让它工作 agrep asdf fdsa asdf fixed F integer 0 以上should匹配正则表达式
  • 使用 Codeigniter 将复选框值传递到 mysql 数据库

    我正在使用 CodeIgniter 和 mySQL 构建复选框表单 该表格包含 4 个选项 每个选项只有一个复选框 用户可以选择选项的任意组合 我想做以下事情 1 对于每个复选框 使用值 1 如果未选中 或 2 如果选中 并将这些值传递到数
  • 第一个项目需要注意什么

    我想创建一个程序 它将接受用户输入并创建一个 使用输入的日历 示例 约翰 康纳 2010 年 1 月 3 日生日 此信息还可按明显的顺序排序 姓氏 名字 日期 其他 它将能够将此信息打印为列表或日历 必须有例外 例如 1 3 10 放在 2
  • JTable 编辑/取消编辑代码不适用于重新排列的 JTable 列

    我使用以下代码对 JTable 列进行编辑 取消编辑 但是当用户重新排列列时 以下代码不起作用 SSCCE的代码如下 import javax swing JTable import javax swing table DefaultTab
  • System.Web.Routing.RouteCollection.GetRouteData 中的异常

    我在 iis7 上运行的 ASP NET MVC 代码中随机出现两个异常 Exception type InvalidOperationException Exception message Collection was modified
  • jquery Accordion - 从外部链接单击返回时记住活动区域

    我的链接位于页面上的 jquery 手风琴内部 当访问者单击其中一个链接然后单击后退按钮返回我的页面时 我希望打开包含该链接的手风琴 我的假设是我应该使用 navigation true 设置并将主题标签添加到不同的手风琴 但这对我不起作用
  • Instagram 基本显示 API 错误 - 无效范围:['basic'] 或无效的 redirect_uri

    我正在使用 Magento 2 4 1 安装了社交登录扩展 并在登录 Instagram 时出现以下错误 我正在使用混合身份验证库进行登录 error type OAuthException 代码 400 error message 无效
  • Linux Xwindow 转发上的 Visual Studio Code

    我的配置如下 OS DISTRIB ID Ubuntu DISTRIB RELEASE 14 04 DISTRIB CODENAME trusty DISTRIB DESCRIPTION Ubuntu 14 04 4 LTS NAME Ub
  • 更新 my.cnf 中的变量

    I set lower case table names 2在 my cnf 文件中 设置变量后 我重新启动了 mysql 服务器 但当我使用时 该值仍然是 0SHOW VARIABLES 我正在使用 MySQL 5 5 任何想法还需要做什
  • HTML:阻止子元素继承父元素的 [title] 属性

    问题是 当我为 wrapper 元素声明标题属性时 当光标落入 content 元素内时 也会显示工具提示 如何防止这种情况 继承 发生 div title example div div div 我只想显示工具提示between cont
  • 如何使用 gradle 任务解析 .json 文件并从中获取 json 数据?

    有没有一种方法可以在 gradle 任务的帮助下解析 xyz json 文件并获取其中的所有单独的 json 数据 例如 我想解析存储在我的资产文件夹中的 xyz json 文件中的数据并获取其中的所有值 例如 获取 类型 的值 type
  • 在CSS中创建凹角[重复]

    这个问题在这里已经有答案了 是否可以在CSS中创建这样的凹角 如果是 你会怎么做 莉亚 维鲁有一个如何执行此操作的描述 http lea verou me 2011 03 beveled corners negative border ra
  • 使用 jQuery getJSON 时 JSON Feed 返回 null

    http portlandonline com shared cfm json cfm c 27321 http portlandonline com shared cfm json cfm c 27321 它返回 null 我真的无权接触
  • 匿名委托中捕获的私有字段

    class A public event EventHandler AEvent class B private A foo private int bar public void AttachToAEvent foo AEvent del
  • 数据工厂子项修改或创建日期

    我有一个数据工厂 V2 管道 由 获取元数据 和 forEach 活动组成 用于读取文件共享 本地 上的文件列表并将其记录在数据库表中 目前 我只能读取文件名 但还想检索每个文件的修改日期和 或创建日期属性 有什么帮助吗 谢谢 Accord
  • 使用SQL计算时间序列中的时间间隔

    我有一个像这样的 MySQL 表 CREATE TABLE IF NOT EXISTS vals DT datetime NOT NULL value INT 11 NOT NULL PRIMARY KEY DT DT 是唯一的日期和时间
  • iOS 自定义字体已移位

    对于一个项目我买了一个OTF字体并将其包含到我的项目中 添加到 plist 文件等 它有效 我可以在按钮上设置字体 但标签会被替换 我添加了屏幕截图 以便您可以看到我的问题 有人知道问题出在哪里吗 系统 iPad 3 iOS 6 0 bet
  • 有什么办法可以提取底层Xaml吗?

    无论如何 是否可以从控件中提取底层 xaml IE 我有一个名为 fooBox 的文本框 我可以在运行时从文本框获取代表文本框的 xaml 吗 这向您展示了完整的生命周期 从控件到 XAML 再到控件 如你看到的 string s Xaml
  • 有保证的方法可以在运行时获取成员字段的源顺序吗?

    我正在寻找一种按源顺序检索 在运行时 类的字段的方法 以便我可以执行自己的 初始化处理 该处理基于声明的顺序 我知道 Javadoc 用于Class getDeclaredFields 明确指出不保证订单 SO 上的一些答案指向Javass