命令查看java的class字节码文件、verbose、synchronize、javac、javap

查看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:\shiva\omcs\Test\src\sync>javac -verbose Test.java
[解析开始时间 RegularFileObject[Test.java]]
[解析已完成, 用时 68 毫秒]
[源文件的搜索路径: .,C:\Java\jdk1.8.0_31\lib,C:\Java\jdk1.8.0_31\lib\tools.jar]
[类文件的搜索路径: C:\Java\jdk1.8.0_31\jre\lib\resources.jar,C:\Java\jdk1.8.0_31\jre\lib\rt.jar,C:\Java\jdk1.8.0_31\jre
lib\sunrsasign.jar,C:\Java\jdk1.8.0_31\jre\lib\jsse.jar,C:\Java\jdk1.8.0_31\jre\lib\jce.jar,C:\Java\jdk1.8.0_31\jre\lib
charsets.jar,C:\Java\jdk1.8.0_31\jre\lib\jfr.jar,C:\Java\jdk1.8.0_31\jre\classes,C:\Java\jdk1.8.0_31\jre\lib\ext\access
bridge-64.jar,C:\Java\jdk1.8.0_31\jre\lib\ext\cldrdata.jar,C:\Java\jdk1.8.0_31\jre\lib\ext\dnsns.jar,C:\Java\jdk1.8.0_3
\jre\lib\ext\jaccess.jar,C:\Java\jdk1.8.0_31\jre\lib\ext\jfxrt.jar,C:\Java\jdk1.8.0_31\jre\lib\ext\localedata.jar,C:\Ja
a\jdk1.8.0_31\jre\lib\ext\nashorn.jar,C:\Java\jdk1.8.0_31\jre\lib\ext\sunec.jar,C:\Java\jdk1.8.0_31\jre\lib\ext\sunjce_
rovider.jar,C:\Java\jdk1.8.0_31\jre\lib\ext\sunmscapi.jar,C:\Java\jdk1.8.0_31\jre\lib\ext\sunpkcs11.jar,C:\Java\jdk1.8.
_31\jre\lib\ext\zipfs.jar,.,C:\Java\jdk1.8.0_31\lib,C:\Java\jdk1.8.0_31\lib\tools.jar]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Object.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/String.class)]]
[正在检查sync.Test]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/io/Serializable.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/AutoCloseable.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Byte.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Character.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Short.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Long.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Float.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Integer.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Double.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Boolean.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Void.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/System.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/io/PrintStream.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/io/FilterOutputStream.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/io/OutputStream.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Comparable.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/CharSequence.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Appendable.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/io/Closeable.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/io/Flushable.class)]]
[正在加载ZipFileIndexFileObject[C:\Java\jdk1.8.0_31\lib\ct.sym(META-INF/sym/rt.jar/java/lang/Throwable.class)]]
[已写入RegularFileObject[Test.class]]
[共 620 毫秒]

D:\shiva\omcs\Test\src\sync>

可以看到虚拟机编译时做了那些事情……

java -verbose Test

可以看到虚拟机运行一个程序时加载的jar包

更多内容查看javac –help命令

2  javap查看字节码

首先使用javap –help可以查看到各种命令,各个命令什么作用,可以自己运行试试……

这里只是测试 javap –c和javap –verbose

javap –c HelloWorld

D:\shiva\omcs\Test\bin\sync>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:\shiva\omcs\Test\bin\sync>cd ..

可以查看字节码,从中可以得到各种变量的信息等等

但是javap –verbose可以看到更加清楚的信息。如下图

D:\shiva\omcs\Test\bin\sync>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:\shiva\omcs\Test\bin\sync>

以上为命令查看java字节码文件过程,对了解java背后的秘密,深层次理解java有用

posted on 2016-11-15 17:48  duanxz  阅读(760)  评论(0编辑  收藏