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

时间:2023-03-08 20:33:00

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

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

java -verbose Test

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

可以看到虚拟机运行一个程序时加载的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:
: aload_0
: invokespecial # // Method java/lang/Object."<init>":()V
: return public static void main(java.lang.String[]);
Code:
: new # // class java/lang/Object
: dup
: invokespecial # // Method java/lang/Object."<init>":()V
: astore_1
: aload_1
: dup
: astore_2
: monitorenter
: getstatic # // Field java/lang/System.out:Ljava/io/PrintStream;
: ldc # // String hello world.
: invokevirtual # // Method java/io/PrintStream.println:(Ljava/lang/String;)V
: aload_2
: monitorexit
: goto
: aload_2
: monitorexit
: athrow
: return
Exception table:
from to target type
any
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 --; size bytes
MD5 checksum 954bd4bcfcff2732e5be9925e518e79a
Compiled from "Test.java"
public class sync.Test
minor version:
major version:
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
# = Class # // sync/Test
# = Utf8 sync/Test
# = Class # // java/lang/Object
# = Utf8 java/lang/Object
# = Utf8 <init>
# = Utf8 ()V
# = Utf8 Code
# = Methodref #.# // java/lang/Object."<init>":()V
# = NameAndType #:# // "<init>":()V
# = Utf8 LineNumberTable
# = Utf8 LocalVariableTable
# = Utf8 this
# = Utf8 Lsync/Test;
# = Utf8 main
# = Utf8 ([Ljava/lang/String;)V
# = Fieldref #.# // java/lang/System.out:Ljava/io/PrintStream;
# = Class # // java/lang/System
# = Utf8 java/lang/System
# = NameAndType #:# // out:Ljava/io/PrintStream;
# = Utf8 out
# = Utf8 Ljava/io/PrintStream;
# = String # // hello world.
# = Utf8 hello world.
# = Methodref #.# // java/io/PrintStream.println:(Ljava/lang/String;)V
# = Class # // java/io/PrintStream
# = Utf8 java/io/PrintStream
# = NameAndType #:# // println:(Ljava/lang/String;)V
# = Utf8 println
# = Utf8 (Ljava/lang/String;)V
# = Utf8 args
# = Utf8 [Ljava/lang/String;
# = Utf8 lock
# = Utf8 Ljava/lang/Object;
# = Utf8 StackMapTable
# = Class # // "[Ljava/lang/String;"
# = Class # // java/lang/Throwable
# = Utf8 java/lang/Throwable
# = Utf8 SourceFile
# = Utf8 Test.java
{
public sync.Test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=, locals=, args_size=
: aload_0
: invokespecial # // Method java/lang/Object."<init>":()V
: return
LineNumberTable:
line :
LocalVariableTable:
Start Length Slot Name Signature
this Lsync/Test; public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=, locals=, args_size=
: new # // class java/lang/Object
: dup
: invokespecial # // Method java/lang/Object."<init>":()V
: astore_1
: aload_1
: dup
: astore_2
: monitorenter
: getstatic # // Field java/lang/System.out:Ljava/io/PrintStream;
: ldc # // String hello world.
: invokevirtual # // Method java/io/PrintStream.println:(Ljava/lang/String;)V
: aload_2
: monitorexit
: goto
: aload_2
: monitorexit
: athrow
: return
Exception table:
from to target type
any
any
LineNumberTable:
line :
line :
line :
line :
line :
LocalVariableTable:
Start Length Slot Name Signature
args [Ljava/lang/String;
lock Ljava/lang/Object;
StackMapTable: number_of_entries =
frame_type = /* full_frame */
offset_delta =
locals = [ class "[Ljava/lang/String;", class java/lang/Object, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = /* chop */
offset_delta =
}
SourceFile: "Test.java" D:\shiva\omcs\Test\bin\sync>

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