Javap output: difference between static {} and public {}

I have two examples of class files, one from an example Java application and one from an example C application (compiled into bytecode using LLJVM).

Having looked at their outputs, I see through javap -c -p that for initializing (static) fields, a Java application shows the following block:

static {}; Code: 0: sipush 1339 3: putstatic #7 //Field SRV_ID etc 

This is essentially a <clinit> method, if I understand it. Or is detected as such using the virtual machine that I use.

The C-app has the following:

 public {}; Code: 0: sipush 1339 3: putstatic #7 //Field SRV_ID etc 

What is it? My virtual machine does not detect it.

Examples of class files. First, from a Java application that prints a message and waits 20 seconds, repeat. The second is a C application, which does roughly the same thing.

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

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

Apologize for this, I do not immediately know how to attach files or display .class files efficiently.

+8
java jvm bytecode bytecode-manipulation jvm-bytecode
source share
1 answer

This is apparently a custom declaration that javap did not take into account. Typically, static initializers are compiled into bytecode methods called <clinit> with a static modifier. Apparently, javap decodes them by simply printing out the readable form of the modifier and omitting the name <clinit> .

Here he came across a method called <clinit> and a public (no static ) modifier and simply did the same as a regular modifier by typing the modifier and omitting the name <clinit> .

The code generated by LLJVM relies on the old weirdness :

In a class file whose version number is 51.0 or higher, this method must additionally have its own ACC_STATIC flag (§4.6) in order to be a method of initializing a class or interface.

This requirement was introduced in Java SE 7. In a class file whose version number is 50.0 or lower, a method named <clinit> , which is invalid and does not accept any arguments, is considered the method of initializing the class or interface, regardless of its flag setting ACC_STATIC

It was surprising to me to read that in previous versions the ACC_STATIC modifier ACC_STATIC not assigned, and I see no reason to ever use this oddity. It seems that the class initializer (declared static {} in Java) should have the ACC_STATIC flag, and I can’t even imagine the supposed semantics of the missing ACC_STATIC flag. This means that one of two odd things must happen: a) it is called without an instance, despite the fact that the ACC_STATIC flag (which is called as if it is) or b) it is called with an instance that must be created “magically” .

The specification reports the following about any non-standard <clinit> method:

Other methods named <clinit> in the class file have no meaning. They are not methods of initializing a class or interface. They cannot be called by any Java Virtual Machine instruction and are never called by the Java virtual machine itself.

+4
source share

All Articles