详细分解classFile常量池(HelloWorld)

当一个java文件被javac编译之后,就可以成为一个通用的class文件格式。我们之前说JVM里面的运行期常量池,主要也就是说的从classFile中读取的常量信息。作为JVM来说,它并没有对类,接口,实例等有一个内部的数据结构,所有的指令的引用信息均来自于常量池中。
Java Virtual Machine instructions do not rely on the run-time layout of classes, interfaces, class instances, or arrays. Instead, instructions refer to symbolic information in the constant_pool table.
本文自:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html 4.4节

这里,我们有一个很简单的HelloWorld例子,如下所示:

public class T {
    public static void main(String args[]) {
        String s = "abcdefghijk";
        System.out.println(s);
    }
}

采用指令:javac -g:none T.java进行编译。编译之后产生的class如下所示:

Offset     0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   CA FE BA BE 00 00 00 33  00 1A 0A 00 06 00 0C 08     3        
00000010   00 0D 09 00 0E 00 0F 0A  00 10 00 11 07 00 12 07                   
00000020   00 13 01 00 06 3C 69 6E  69 74 3E 01 00 03 28 29        <init>   ()
00000030   56 01 00 04 43 6F 64 65  01 00 04 6D 61 69 6E 01   V   Code   main 
00000040   00 16 28 5B 4C 6A 61 76  61 2F 6C 61 6E 67 2F 53     ([Ljava/lang/S
00000050   74 72 69 6E 67 3B 29 56  0C 00 07 00 08 01 00 0B   tring;)V        
00000060   61 62 63 64 65 66 67 68  69 6A 6B 07 00 14 0C 00   abcdefghijk     
00000070   15 00 16 07 00 17 0C 00  18 00 19 01 00 01 54 01                 T 
00000080   00 10 6A 61 76 61 2F 6C  61 6E 67 2F 4F 62 6A 65     java/lang/Obje
00000090   63 74 01 00 10 6A 61 76  61 2F 6C 61 6E 67 2F 53   ct   java/lang/S
000000A0   79 73 74 65 6D 01 00 03  6F 75 74 01 00 15 4C 6A   ystem   out   Lj
000000B0   61 76 61 2F 69 6F 2F 50  72 69 6E 74 53 74 72 65   ava/io/PrintStre
000000C0   61 6D 3B 01 00 13 6A 61  76 61 2F 69 6F 2F 50 72   am;   java/io/Pr
000000D0   69 6E 74 53 74 72 65 61  6D 01 00 07 70 72 69 6E   intStream   prin
000000E0   74 6C 6E 01 00 15 28 4C  6A 61 76 61 2F 6C 61 6E   tln   (Ljava/lan
000000F0   67 2F 53 74 72 69 6E 67  3B 29 56 00 21 00 05 00   g/String;)V !   
00000100   06 00 00 00 00 00 02 00  01 00 07 00 08 00 01 00                   
00000110   09 00 00 00 11 00 01 00  01 00 00 00 05 2A B7 00                *?
00000120   01 B1 00 00 00 00 00 09  00 0A 00 0B 00 01 00 09    ?             
00000130   00 00 00 17 00 02 00 02  00 00 00 0B 12 02 4C B2                 L?
00000140   00 03 2B B6 00 04 B1 00  00 00 00 00 00                   +? ?     

本文是描述如何从这个classFile中详细的找出相应的常量池信息,从文件本身描述的信息中手动地找出相应的内部结构,以方便进一步掌握class的结构形式,以方便了解JVM规范及组织。

继续阅读“详细分解classFile常量池(HelloWorld)”