What commands can I use to view the details of certain Java classes ?
When I see the
JVM spec, it says that there is at most one class initialization method per class, and that’s “clinit”, so I think we should have some commands to see how this method is coded in the .class file.
At first I thought it would work with javap, but it didn’t.
Solution
The javap
command shows the <init>
and <clinit>
methods… Although it does not use these names for them. (See public Test() below);
and static {};
Method. )
Alternatively, you can use another disassembler. For example, Krakatau will display the internal names “<init>” and “<clinit>"
in its output.
I had always thought there was a method name
<clinit>
in the.class
file
You are right. These names will appear in the file representation of the method in .class
. You can see the internal method names <init>
and <clinit>
in the constant table printed by javap
.
It’s just that the implementer of javap
| Choose not to display these method names in the Methods section. They used different symbols.
(Why?) I guess they think it would be easier for most people to understand the javap output if they did that! Are they right? I don’t know, but it doesn’t make practical sense anyway. )
$ cat Test.java
public class Test {
static String foo = "hello";
}
$ javap -p -c -s -v Test
Classfile /tmp/Test.class
Last modified Feb 23, 2019; size 293 bytes
MD5 checksum 724ea13308a150d0cc5730edcf4db616
Compiled from "Test.java"
public class Test
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #5.#15 // java/lang/Object." <init>":()V
#2 = String #16 // hello
#3 = Fieldref #4.#17 // Test.foo:Ljava/lang/String;
#4 = Class #18 // Test
#5 = Class #19 // java/lang/Object
#6 = Utf8 foo
#7 = Utf8 Ljava/lang/String;
#8 = Utf8 <init>
#9 = Utf8 ()V
#10 = Utf8 Code
#11 = Utf8 LineNumberTable
#12 = Utf8 <clinit>
#13 = Utf8 SourceFile
#14 = Utf8 Test.java
#15 = NameAndType #8:#9 // "<init>":()V
#16 = Utf8 hello
#17 = NameAndType #6:#7 // foo:Ljava/lang/String;
#18 = Utf8 Test
#19 = Utf8 java/lang/Object
{
static java.lang.String foo;
descriptor: Ljava/lang/String;
flags: ACC_STATIC
public Test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object." <init>":()V
4: return
LineNumberTable:
line 1: 0
static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: ldc #2 // String hello
2: putstatic #3 // Field foo:Ljava/lang/String;
5: return
LineNumberTable:
line 2: 0
}
SourceFile: "Test.java"