问题:
1.如何将.java文件转化为.class文件?
2.class文件的内部结构是怎样的?如何查看它的内部结构内容?
3.字节码是什么?
一、先介绍两个命令
1)javac
将java文件编译成class文件
比如:HelloWorld.java ==> HelloWorld.class
java -g HelloWorld.java 可生成更多的调试信息
HelloWorld.java如下:
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello world!"); } }
2)javap
反编译命令,解析class文件内容,通过该命令可以查看class内部结构
➜ MyGithub javap Usage: javap <options> <classes> where possible options include: -help --help -? Print this usage message -version Version information -v -verbose Print additional information -l Print line number and local variable tables -public Show only public classes and members -protected Show protected/public classes and members -package Show package/protected/public classes and members (default) -p -private Show all classes and members -c Disassemble the code -s Print internal type signatures -sysinfo Show system info (path, size, date, MD5 hash) of class being processed -constants Show final constants -classpath <path> Specify where to find user class files -cp <path> Specify where to find user class files -bootclasspath <path> Override location of bootstrap class files
javap 有比较多的参数选项,其中-c -v -l -p -s是最常用的。
* -c选项 查看方法的字节码
* -p 选项 加上 -p 选项以后可以显示 private 方法和字段
* -v 选项 javap 加上 -v 参数的输出更多详细的信息,比如栈大小、方法参数的个数
* -s选项 javap 还有一个好用的选项 -s,可以输出签名的类型描述符
使用举例:
➜ class_file_structure git:(master) ✗ javac -g HelloWorld.java ➜ class_file_structure git:(master) ✗ javap -v HelloWorld Warning: Binary file HelloWorld contains class_file_structure.HelloWorld Classfile /Users/zhangboqing/Software/MyGithub/jvm-learn/src/class_file_structure/HelloWorld.class Last modified Mar 25, 2020; size 576 bytes MD5 checksum b1b8e90955cb68d91542d5956431527e Compiled from "HelloWorld.java" public class class_file_structure.HelloWorld minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #6.#20 // java/lang/Object."<init>":()V #2 = Fieldref #21.#22 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #23 // Hello world! #4 = Methodref #24.#25 // java/io/PrintStream.println:(Ljava/lang/String;)V #5 = Class #26 // class_file_structure/HelloWorld #6 = Class #27 // java/lang/Object #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8 Lclass_file_structure/HelloWorld; #14 = Utf8 main #15 = Utf8 ([Ljava/lang/String;)V #16 = Utf8 args #17 = Utf8 [Ljava/lang/String; #18 = Utf8 SourceFile #19 = Utf8 HelloWorld.java #20 = NameAndType #7:#8 // "<init>":()V #21 = Class #28 // java/lang/System #22 = NameAndType #29:#30 // out:Ljava/io/PrintStream; #23 = Utf8 Hello world! #24 = Class #31 // java/io/PrintStream #25 = NameAndType #32:#33 // println:(Ljava/lang/String;)V #26 = Utf8 class_file_structure/HelloWorld #27 = Utf8 java/lang/Object #28 = Utf8 java/lang/System #29 = Utf8 out #30 = Utf8 Ljava/io/PrintStream; #31 = Utf8 java/io/PrintStream #32 = Utf8 println #33 = Utf8 (Ljava/lang/String;)V { public class_file_structure.HelloWorld(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 7: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lclass_file_structure/HelloWorld; public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String Hello world! 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 10: 0 line 11: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 args [Ljava/lang/String; } SourceFile: "HelloWorld.java" ➜ class_file_structure git:(master) ✗ javap -s HelloWorld Warning: Binary file HelloWorld contains class_file_structure.HelloWorld Compiled from "HelloWorld.java" public class class_file_structure.HelloWorld { public class_file_structure.HelloWorld(); descriptor: ()V public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V } ➜ class_file_structure git:(master) ✗ javap HelloWorld Warning: Binary file HelloWorld contains class_file_structure.HelloWorld Compiled from "HelloWorld.java" public class class_file_structure.HelloWorld { public class_file_structure.HelloWorld(); public static void main(java.lang.String[]); } ➜ class_file_structure git:(master) ✗ javap -p HelloWorld Warning: Binary file HelloWorld contains class_file_structure.HelloWorld Compiled from "HelloWorld.java" public class class_file_structure.HelloWorld { public class_file_structure.HelloWorld(); public static void main(java.lang.String[]); } ➜ class_file_structure git:(master) ✗ javap -c HelloWorld Warning: Binary file HelloWorld contains class_file_structure.HelloWorld Compiled from "HelloWorld.java" public class class_file_structure.HelloWorld { public class_file_structure.HelloWorld(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String Hello world! 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return }