何时设置 JVM 字节码访问修饰符标志 0x1000(十六进制)“合成”?

2023-12-22

对于某些 Java 字节码解析器项目,我阅读了 JVM 规范,发现 Java 虚拟机类文件格式访问修饰符字段的位掩码值是

  ACC_PUBLIC = 0x0001
  ACC_FINAL = 0x0010
  ACC_SUPER = 0x0020 # old invokespecial instruction semantics (Java 1.0x?)
  ACC_INTERFACE = 0x0200
  ACC_ABSTRACT = 0x0400
  ACC_SYNTHETIC = 0x1000 
  ACC_ANNOTATION = 0x2000
  ACC_ENUM = 0x4000

不知怎的,我不知道是什么0x1000是为了.我在内部类中看到过一次,但是对于从那时起我检查过的所有内部类,这个标志从未设置过。您现在知道该标志的含义是什么以及它在何处/何时设置?


合成元素是存在于编译的类文件中但不存在于编译它的源代码中的任何元素。通过检查某个元素是否是合成的,您可以区分这些元素以用于反射处理代码的工具。这当然首先与使用反射的库相关,但也与其他工具(例如 IDE)相关,这些工具不允许您调用合成方法或使用合成类。最后,对于 Java 编译器来说,在编译期间验证代码不要直接使用合成元素也很重要。合成元素仅用于使 Java 运行时满意,它只是处理(并验证)所交付的代码,其中合成元素与任何其他元素的处理方式相同。

您已经提到内部类作为 Java 编译器插入合成元素的示例,所以让我们看一下这样的类:

class Foo {

  private String foo;

  class Bar {

    private Bar() { }

    String bar() {
      return foo;
    }
  }

  Bar bar() {
    return new Bar();
  }
}

编译效果非常好,但如果没有合成元素,它会被对内部类一无所知的 JVM 拒绝。 Java编译器德糖雷斯上面的类类似于以下内容:

class Foo {

  private String foo;

  String access$100() {  // synthetic method
    return foo;
  }

  Foo$Bar bar() {
    return new Foo$Bar(this, (Foo$1)null);
  }

  Foo() { } // NON-synthetic, but implicit!
}

class Foo$Bar {

  private final Foo $this; // synthetic field

  private Foo$Bar(Foo $this) {  // synthetic parameter
    this.$this = $this;
  }

  Foo$Bar(Foo $this, Foo$1 unused) {  // synthetic constructor
    this($this);
  }

  String bar() {
    return $this.access$100();
  }
}

class Foo$1 { /*empty, no constructor */ } // synthetic class

如前所述,JVM 不知道内部类,但强制执行成员的私有访问,即内部类将无法访问其封闭类的私有属性。因此,Java 编译器需要向被访问的类添加所谓的访问器,以公开其不可见属性:

  1. The foo字段是私有的,因此只能从内部访问Foo. The access$100方法将此字段公开给其包,在该包中始终可以找到内部类。该方法是合成的,因为它是由编译器添加的。

  2. The Bar构造函数是私有的,因此只能从其自己的类中调用。为了实例化一个实例Bar,另一个(合成)构造函数需要公开实例的构造。然而,构造函数有一个固定的名称(在内部,它们都被称为<init>),因此我们不能将这种技术应用于我们简单命名的方法访问器access$xxx。相反,我们通过创建合成类型来使构造函数访问器变得唯一Foo$1.

  3. 为了访问其外部实例,内部类需要存储对此实例的引用,该引用存储在合成字段中$this。该引用需要通过构造函数中的合成参数传递给内部实例。

合成元素的其他示例包括表示 lambda 表达式的类、使用不同类型签名重写方法时的桥接方法、创建Proxy类或由其他工具(例如 Maven 构建或运行时代码生成器)创建的类,例如字节好友 http://bytebuddy.net(无耻的插头)。

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

何时设置 JVM 字节码访问修饰符标志 0x1000(十六进制)“合成”? 的相关文章

随机推荐

  • 录制视频时的音频音量

    因此 经过大量搜索后 我找到了允许在录制视频的同时播放背景音频的代码块 我已将所述代码块粘贴在下面 fileprivate func setBackgroundAudioPreference guard allowBackgroundAud
  • 枚举内的枚举

    我想在 java 中的 sql 查询的枚举中创建一个枚举 比如我想说table create它会返回 CREATE TABLE 或database create它会返回创建数据库 我怎样才能做到这一点 enum SQL table ALTE
  • 未找到 Phonegap 3.0 IOS 插件

    我在 XCode 中收到此错误 2013 08 23 14 36 18 284 Tell The DJ 14955 c07 ERROR Plugin Device not found or is not a CDVPlugin Check
  • 我可以使用 UriTemplate 将非字符串传递给 WCF RESTful 服务吗?

    我可以执行以下操作吗 OperationContract WebGet UriTemplate foo id string GetFoo int id 我希望我的服务既可以作为 RESTful 服务 又可以作为 RPC 样式的 SOAP 服
  • 如何在C++中链接头文件

    我是使用头文件进行 C 编程的新手 这是我当前的代码 a h ifndef a H define a H namespace hello class A int a public void setA int x int getA endif
  • 如何在 Swift 中从文件夹中获取 UIImage 数组?

    我有一个像这样的普通 Xcode 项目 请注意 有一个名为 images 的文件夹 它是一个实际的文件夹 而不仅仅是一个组 它包含 25 个 png 图像 我想做的就是做一个array of UIimage与每一个图像 或者甚至是图像名称或
  • 使用 register_shutdown_function() 处理 PHP 中的致命错误

    根据对此答案的评论 https stackoverflow com questions 4409426 can i hook a method to my php file that if any page crashes should e
  • 模糊错误表明我的组件名称以零开头

    我收到一个晦涩的错误 我的组件名称为零 但我的组件中没有一个名称是零 这个错误很难追踪 任何人都知道问题可能是什么 这样我就可以朝着正确的方向前进来解决它 vendor js 66537 Vue warn 无效的组件名称 0 组件名称只能包
  • 无法将 Spring Security BASIC 身份验证集成到 Jersey/JAX-RS 和 Tomcat 中

    我正在尝试将 BASIC 身份验证添加到我使用 Jersey JAX RS 和 Tomcat Apache 7 0 创建的 RESTful Web 服务 将来我想在 WebSphere 上部署此 Web 服务 因此我选择在我的项目中使用 S
  • 优化大向量的操作

    这是我的后续行动上一个问题 https stackoverflow com questions 24278006 need advice on optimising haskell data processing关于处理 5 1m 边有向图
  • 自定义 HTML 插件创建 index.html 不影响

    我已经创建了这样的自定义 xhtml 插件 我的plugin xml代码是
  • 关于布局别名的 Android 文档不正确?

    我想弄清楚如何使用最少的样板代码重用或 别名 布局 看来关于布局别名的 Android 文档 http developer android com training multiscreen screensizes html TaskUseA
  • 带有 React useEffect 钩子的 componentWillUnmount

    怎样才能useEffect钩子 或任何其他与此相关的钩子 用于复制componentWillUnmount 在传统的类组件中我会做这样的事情 class Effect extends React PureComponent componen
  • StartPosition 设置为 CenterPosition 但我的表单未居中

    我正在使用 Visual Studio 2012 我的表单打开时不会以屏幕为中心 我有表格StartPosition set to CenterScreen 但它总是从我的左显示器的左上角开始 我有 2 个显示器 有任何想法吗 谢谢 试试这
  • 删除长度为 1 的 Julia 数组维度

    假设我有一个大小为 1024x1024x1x1x100 的 5D 数组 如何制作一个 1024x1024x100 的新数组 如果您提前知道要保留哪些维度 则以下操作有效 arr arr 1 1 But 我提前不知道哪些尺寸是多少我只想保留给
  • Databricks 笔记本挂着 pytorch

    我们遇到 Databricks 笔记本问题 我们的一个笔记本单元似乎挂起 而驱动程序日志确实显示该笔记本单元已被执行 有谁知道为什么我们的笔记本单元一直挂起并且无法完成 请参阅下面的详细信息 情况 我们正在训练 ML 模型pytorch在
  • 如何使用 Photoshop JavaScript 将文本写入文本文件?

    我看了一下Photoshop CS5 脚本编写指南和 Photoshop CS5 JavaScript 参考 http www adobe com devnet photoshop scripting html 但我找不到将文本写入纯文本文
  • 如何使用 TensorFlow 实现 k-means?

    介绍教程使用内置的梯度下降优化器 非常有意义 然而 k 均值不仅仅是我可以插入梯度下降中的东西 看起来我必须编写自己的优化器 但考虑到 TensorFlow 原语 我不太确定如何做到这一点 我应该采取什么方法 注 您现在可以获得这段代码的更
  • 如何用 C++ 确定 Linux 系统 RAM 的大小?

    我刚刚编写了以下 C 函数来以编程方式确定系统安装了多少 RAM 它有效 但在我看来应该有一种更简单的方法来做到这一点 我错过了什么吗 getRAM FILE stream popen head n1 proc meminfo r std
  • 何时设置 JVM 字节码访问修饰符标志 0x1000(十六进制)“合成”?

    对于某些 Java 字节码解析器项目 我阅读了 JVM 规范 发现 Java 虚拟机类文件格式访问修饰符字段的位掩码值是 ACC PUBLIC 0x0001 ACC FINAL 0x0010 ACC SUPER 0x0020 old inv