查看Java字节码
1 javac –verbose查看运行类是加载了那些jar文件
HelloWorld演示:
public class Test { public static void main(String[] args) { Object lock = new Object(); synchronized (lock) { System.out.println("hello world."); } } }
javac –verbose HelloWorld.java
D:shivaomcsTestsrcsync>javac -verbose Test.java [解析开始时间 RegularFileObject[Test.java]] [解析已完成, 用时 68 毫秒] [源文件的搜索路径: .,C:Javajdk1.8.0_31lib,C:Javajdk1.8.0_31libtools.jar] [类文件的搜索路径: C:Javajdk1.8.0_31jrelib esources.jar,C:Javajdk1.8.0_31jrelib t.jar,C:Javajdk1.8.0_31jre libsunrsasign.jar,C:Javajdk1.8.0_31jrelibjsse.jar,C:Javajdk1.8.0_31jrelibjce.jar,C:Javajdk1.8.0_31jrelib charsets.jar,C:Javajdk1.8.0_31jrelibjfr.jar,C:Javajdk1.8.0_31jreclasses,C:Javajdk1.8.0_31jrelibextaccess bridge-64.jar,C:Javajdk1.8.0_31jrelibextcldrdata.jar,C:Javajdk1.8.0_31jrelibextdnsns.jar,C:Javajdk1.8.0_3 jrelibextjaccess.jar,C:Javajdk1.8.0_31jrelibextjfxrt.jar,C:Javajdk1.8.0_31jrelibextlocaledata.jar,C:Ja ajdk1.8.0_31jrelibext ashorn.jar,C:Javajdk1.8.0_31jrelibextsunec.jar,C:Javajdk1.8.0_31jrelibextsunjce_ rovider.jar,C:Javajdk1.8.0_31jrelibextsunmscapi.jar,C:Javajdk1.8.0_31jrelibextsunpkcs11.jar,C:Javajdk1.8. _31jrelibextzipfs.jar,.,C:Javajdk1.8.0_31lib,C:Javajdk1.8.0_31libtools.jar] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Object.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/String.class)]] [正在检查sync.Test] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/io/Serializable.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/AutoCloseable.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Byte.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Character.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Short.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Long.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Float.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Integer.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Double.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Boolean.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Void.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/System.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/io/PrintStream.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/io/FilterOutputStream.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/io/OutputStream.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Comparable.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/CharSequence.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Appendable.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/io/Closeable.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/io/Flushable.class)]] [正在加载ZipFileIndexFileObject[C:Javajdk1.8.0_31libct.sym(META-INF/sym/rt.jar/java/lang/Throwable.class)]] [已写入RegularFileObject[Test.class]] [共 620 毫秒] D:shivaomcsTestsrcsync>
可以看到虚拟机编译时做了那些事情……
java -verbose Test
可以看到虚拟机运行一个程序时加载的jar包
更多内容查看javac –help命令
2 javap查看字节码
首先使用javap –help可以查看到各种命令,各个命令什么作用,可以自己运行试试……
这里只是测试 javap –c和javap –verbose
javap –c HelloWorld
D:shivaomcsTestinsync>javap -c Test 警告: 二进制文件Test包含sync.Test Compiled from "Test.java" public class sync.Test { public sync.Test(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: new #3 // class java/lang/Object 3: dup 4: invokespecial #8 // Method java/lang/Object."<init>":()V 7: astore_1 8: aload_1 9: dup 10: astore_2 11: monitorenter 12: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 15: ldc #22 // String hello world. 17: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 20: aload_2 21: monitorexit 22: goto 28 25: aload_2 26: monitorexit 27: athrow 28: return Exception table: from to target type 12 22 25 any 25 27 25 any } D:shivaomcsTestinsync>cd ..
可以查看字节码,从中可以得到各种变量的信息等等
但是javap –verbose可以看到更加清楚的信息。如下图
D:shivaomcsTestinsync>javap -verbose Test 警告: 二进制文件Test包含sync.Test Classfile /D:/shiva/omcs/Test/bin/sync/Test.class Last modified 2016-11-15; size 686 bytes MD5 checksum 954bd4bcfcff2732e5be9925e518e79a Compiled from "Test.java" public class sync.Test minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Class #2 // sync/Test #2 = Utf8 sync/Test #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 <init> #6 = Utf8 ()V #7 = Utf8 Code #8 = Methodref #3.#9 // java/lang/Object."<init>":()V #9 = NameAndType #5:#6 // "<init>":()V #10 = Utf8 LineNumberTable #11 = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8 Lsync/Test; #14 = Utf8 main #15 = Utf8 ([Ljava/lang/String;)V #16 = Fieldref #17.#19 // java/lang/System.out:Ljava/io/PrintStream; #17 = Class #18 // java/lang/System #18 = Utf8 java/lang/System #19 = NameAndType #20:#21 // out:Ljava/io/PrintStream; #20 = Utf8 out #21 = Utf8 Ljava/io/PrintStream; #22 = String #23 // hello world. #23 = Utf8 hello world. #24 = Methodref #25.#27 // java/io/PrintStream.println:(Ljava/lang/String;)V #25 = Class #26 // java/io/PrintStream #26 = Utf8 java/io/PrintStream #27 = NameAndType #28:#29 // println:(Ljava/lang/String;)V #28 = Utf8 println #29 = Utf8 (Ljava/lang/String;)V #30 = Utf8 args #31 = Utf8 [Ljava/lang/String; #32 = Utf8 lock #33 = Utf8 Ljava/lang/Object; #34 = Utf8 StackMapTable #35 = Class #31 // "[Ljava/lang/String;" #36 = Class #37 // java/lang/Throwable #37 = Utf8 java/lang/Throwable #38 = Utf8 SourceFile #39 = Utf8 Test.java { public sync.Test(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 24: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lsync/Test; public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=1 0: new #3 // class java/lang/Object 3: dup 4: invokespecial #8 // Method java/lang/Object."<init>":()V 7: astore_1 8: aload_1 9: dup 10: astore_2 11: monitorenter 12: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 15: ldc #22 // String hello world. 17: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 20: aload_2 21: monitorexit 22: goto 28 25: aload_2 26: monitorexit 27: athrow 28: return Exception table: from to target type 12 22 25 any 25 27 25 any LineNumberTable: line 28: 0 line 29: 8 line 30: 12 line 29: 20 line 33: 28 LocalVariableTable: Start Length Slot Name Signature 0 29 0 args [Ljava/lang/String; 8 21 1 lock Ljava/lang/Object; StackMapTable: number_of_entries = 2 frame_type = 255 /* full_frame */ offset_delta = 25 locals = [ class "[Ljava/lang/String;", class java/lang/Object, class java/lang/Object ] stack = [ class java/lang/Throwable ] frame_type = 250 /* chop */ offset_delta = 2 } SourceFile: "Test.java" D:shivaomcsTestinsync>
以上为命令查看java字节码文件过程,对了解java背后的秘密,深层次理解java有用