Java Class文件格式解析
一、Java Class文件是什么
java语言是跨平台的,所谓一次编写,到处运行。之所以是跨平台的,就是java定义了一套与操作系统,硬件无关的字节码格式,这个字节码就是用java class文件来表示的,java class文件内部定义了虚拟机可以识别的字节码格式,这个格式是平台无关性的,在linux系统或者在windows系统上都是一致的。这个就好比html文件,我们定义好规范,这个系统只要去按照规范显示出来里面的内容就好了。好比html就是class文件,浏览器就是虚拟机一样,通过浏览器去执行html的渲染过程,我们无论是用手机,Windows系统,苹果系统上网,显示出来的内容都是一样。 java虚拟机可以从class文件中加载预定义的字节码,也可以从网络,数据库,消息文件中加载字节码。
二、Java Class文件的格式
1.多个字节的数据采用大端存储
2.class文件采用定义u1、u2、u4来表示无符号的1、2、4字节数据。
简要解释一下:
U4 代表由无符号四个字节组成
u4 magic :是一个固定的数值,java虚拟机里面称为魔数 ,主要是用来标识是否为java虚拟机所支持的文件结构,目前是0xCAFEBABE
u2 minor_version; u2 major_version; 代表次版本号和主版本号
u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; 这里面代表常量池个数以及常量池信息
u2 access_flags : 代表class访问标记,例如:public protected
u2 this_class : 代表这个类的名称 例如 java.lang.Object
u2 super_class : 代表父类名称
u2 interfaces_count; u2 interfaces[interfaces_count]; 实现的接口格式以及接口类名
u2 fields_count; field_info fields[fields_count]; 字段个数以及字段信息
u2 methods_count; method_info methods[methods_count]; 方法个数以及方法信息
u2 attributes_count; attribute_info attributes[attributes_count]; java class文件内部属性信息,和java语言定义的属性没有关系,纯粹就是给java虚拟机用的
class文件实例
/* * Copyright (c) 2015 Javaranger.com. All Rights Reserved. */ package com.javaranger.test; /** * @author tao.wang Date: 16/1/2 Time: 下午12:29 * @version $Id$ */ public class ClassTest { public int id = 100; private String name = "javaranger"; public void test() { int a = 1; int b = 2; int c = a + b; String str = name + ".com"; System.out.println(str); } }
javap -v ClassTest.class
lassfile /Users/ranger/git/transformer/src/main/java/com/javaranger/test/ClassTest.class Last modified 2016-1-2; size 713 bytes MD5 checksum 67738e1dedfacaa7d62444f45d8cc716 Compiled from "ClassTest.java" public class com.javaranger.test.ClassTest SourceFile: "ClassTest.java" minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #13.#25 // java/lang/Object."":()V #2 = Fieldref #12.#26 // com/javaranger/test/ClassTest.id:I #3 = String #27 // javaranger #4 = Fieldref #12.#28 // com/javaranger/test/ClassTest.name:Ljava/lang/String; #5 = Class #29 // java/lang/StringBuilder #6 = Methodref #5.#25 // java/lang/StringBuilder."":()V #7 = Methodref #5.#30 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #8 = String #31 // .com #9 = Methodref #5.#32 // java/lang/StringBuilder.toString:()Ljava/lang/String; #10 = Fieldref #33.#34 // java/lang/System.out:Ljava/io/PrintStream; #11 = Methodref #35.#36 // java/io/PrintStream.println:(Ljava/lang/String;)V #12 = Class #37 // com/javaranger/test/ClassTest #13 = Class #38 // java/lang/Object #14 = Utf8 id #15 = Utf8 I #16 = Utf8 name #17 = Utf8 Ljava/lang/String; #18 = Utf8 #19 = Utf8 ()V #20 = Utf8 Code #21 = Utf8 LineNumberTable #22 = Utf8 test #23 = Utf8 SourceFile #24 = Utf8 ClassTest.java #25 = NameAndType #18:#19 // "":()V #26 = NameAndType #14:#15 // id:I #27 = Utf8 javaranger #28 = NameAndType #16:#17 // name:Ljava/lang/String; #29 = Utf8 java/lang/StringBuilder #30 = NameAndType #39:#40 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #31 = Utf8 .com #32 = NameAndType #41:#42 // toString:()Ljava/lang/String; #33 = Class #43 // java/lang/System #34 = NameAndType #44:#45 // out:Ljava/io/PrintStream; #35 = Class #46 // java/io/PrintStream #36 = NameAndType #47:#48 // println:(Ljava/lang/String;)V #37 = Utf8 com/javaranger/test/ClassTest #38 = Utf8 java/lang/Object #39 = Utf8 append #40 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #41 = Utf8 toString #42 = Utf8 ()Ljava/lang/String; #43 = Utf8 java/lang/System #44 = Utf8 out #45 = Utf8 Ljava/io/PrintStream; #46 = Utf8 java/io/PrintStream #47 = Utf8 println #48 = Utf8 (Ljava/lang/String;)V { public int id; flags: ACC_PUBLIC public com.javaranger.test.ClassTest(); flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: aload_0 5: bipush 100 7: putfield #2 // Field id:I 10: aload_0 11: ldc #3 // String javaranger 13: putfield #4 // Field name:Ljava/lang/String; 16: return LineNumberTable: line 10: 0 line 11: 4 line 12: 10 public void test(); flags: ACC_PUBLIC Code: stack=2, locals=5, args_size=1 0: iconst_1 1: istore_1 2: iconst_2 3: istore_2 4: iload_1 5: iload_2 6: iadd 7: istore_3 8: new #5 // class java/lang/StringBuilder 11: dup 12: invokespecial #6 // Method java/lang/StringBuilder."":()V 15: aload_0 16: getfield #4 // Field name:Ljava/lang/String; 19: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: ldc #8 // String .com 24: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 27: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 30: astore 4 32: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream; 35: aload 4 37: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 40: return LineNumberTable: line 15: 0 line 16: 2 line 17: 4 line 18: 8 line 19: 32 line 20: 40 }
cafe babe 0000 0033 0031 0a00 0d00 1909 000c 001a 0800 1b09 000c 001c 0700 1d0a 0005 0019 0a00 0500 1e08 001f 0a00 0500 2009 0021 0022 0a00 2300 2407 0025 0700 2601 0002 6964 0100 0149 0100 046e 616d 6501 0012 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 0100 063c 696e 6974 3e01 0003 2829 5601 0004 436f 6465 0100 0f4c 696e 654e 756d 6265 7254 6162 6c65 0100 0474 6573 7401 000a 536f 7572 6365 4669 6c65 0100 0e43 6c61 7373 5465 7374 2e6a 6176 610c 0012 0013 0c00 0e00 0f01 000a 6a61 7661 7261 6e67 6572 0c00 1000 1101 0017 6a61 7661 2f6c 616e 672f 5374 7269 6e67 4275 696c 6465 720c 0027 0028 0100 042e 636f 6d0c 0029 002a 0700 2b0c 002c 002d 0700 2e0c 002f 0030 0100 1d63 6f6d 2f6a 6176 6172 616e 6765 722f 7465 7374 2f43 6c61 7373 5465 7374 0100 106a 6176 612f 6c61 6e67 2f4f 626a 6563 7401 0006 6170 7065 6e64 0100 2d28 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 294c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 4275 696c 6465 723b 0100 0874 6f53 7472 696e 6701 0014 2829 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 0100 106a 6176 612f 6c61 6e67 2f53 7973 7465 6d01 0003 6f75 7401 0015 4c6a 6176 612f 696f 2f50 7269 6e74 5374 7265 616d 3b01 0013 6a61 7661 2f69 6f2f 5072 696e 7453 7472 6561 6d01 0007 7072 696e 746c 6e01 0015 284c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 3b29 5600 2100 0c00 0d00 0000 0200 0100 0e00 0f00 0000 0200 1000 1100 0000 0200 0100 1200 1300 0100 1400 0000 3100 0200 0100 0000 112a b700 012a 1064 b500 022a 1203 b500 04b1 0000 0001 0015 0000 000e 0003 0000 000a 0004 000b 000a 000c 0001 0016 0013 0001 0014 0000 0055 0002 0005 0000 0029 043c 053d 1b1c 603e bb00 0559 b700 062a b400 04b6 0007 1208 b600 07b6 0009 3a04 b200 0a19 04b6 000b b100 0000 0100 1500 0000 1a00 0600 0000 0f00 0200 1000 0400 1100 0800 1200 2000 1300 2800 1400 0100 1700 0000 0200 18