首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javap输出:差异静态{}和公共{}

Javap输出:差异静态{}和公共{}
EN

Stack Overflow用户
提问于 2018-03-13 15:00:50
回答 1查看 404关注 0票数 8

我有两个示例类文件,一个来自示例Java应用程序,一个来自示例C应用程序(使用LLJVM编译为字节码)。

查看它们的输出,我可以通过javap -c -p看到,对于初始化(静态)字段,Java应用程序显示了以下块:

代码语言:javascript
复制
static {};
Code: 
0: sipush 1339
3: putstatic   #7     //Field SRV_ID
etc

这基本上就是<clinit>方法,如果我理解的话。或者被我正在使用的VM检测到。

然而,C-应用程序有这样的功能:

代码语言:javascript
复制
public {};
Code: 
0: sipush 1339
3: putstatic   #7     //Field SRV_ID
etc

这是什么?我的VM没有检测到它。

示例类文件。第一个是来自Java的THe,它打印一条消息,等待20多个,重复。第二个是一个C应用程序,它的功能大致相同。

http://www.fast-files.com/getfile.aspx?file=156962

http://www.fast-files.com/getfile.aspx?file=156961

很抱歉这样做-我不知道如何立即附加文件或有效地显示.class文件。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-14 09:37:58

这似乎是javap没有考虑的非标准声明。通常,static初始化器被编译为具有static修饰符的名为<clinit>的字节码方法。显然,javap只是通过打印修饰符的人类可读的形式和省略<clinit>名称来解码它们。

在这里,它遇到了一个名为<clinit>的方法,它有public修饰符(没有static修饰符),并且和往常一样,打印修饰符并省略了<clinit>名称。

LLJVM生成的代码似乎依赖于旧奇

在版本号为51.0或以上的class文件中,该方法必须另外设置其ACC_STATIC标志(§4.6),才能成为类或接口初始化方法。 这个要求是在Java 7中引入的。在版本号为50.0或以下的类文件中,一个名为<clinit>的方法无效且不带任何参数,不管它的ACC_STATIC标志的设置如何,它都被视为类或接口初始化方法。

对我来说,在以前的版本中,ACC_STATIC修饰符并没有被强制使用,我看不出有什么理由去利用这个奇怪的地方。类初始化器(在Java中声明为static {} )应该具有ACC_STATIC标志,这是非常自然的,我甚至无法想象省略ACC_STATIC标志的假定语义。这意味着应该发生两种奇怪的事情之一:( a)它是在没有实例的情况下调用的,尽管它没有ACC_STATIC标志(如果调用它的话)或( b)它是用一个必须是“神奇”创建的实例调用的。

规格说明对任何非标准的<clinit>方法都做了如下说明:

在一个<clinit>文件中名为class的其他方法没有任何意义。它们不是类或接口初始化方法。任何Java虚拟机指令都不能调用它们,Java虚拟机本身也不会调用它们。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49259422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档