深入Class文件结构
方法的字节码
构造方法的字节码:public <init> ()V
这是一个公有的无参构造方法,返回值类型是"V"(也就是void,很奇怪,构造方法明明没有返回值,还使用V表示),"
main方法的字节码:public static main([Ljava/lang/String;)V
它的参数是一个String类型的数组,其中"["表示数组,而"L"表示一个类形式而不是基本数据类型(如int, long等),方式"L"表示的类后面都会以";"结尾,表示这个类的结束
class文件头信息
字节码文件的前4个字节是一个32位的无符号整型,“cafebabe”是这个整数的16进制表示形式。如果一个class文件的前4的字节是这个数字,则表示这个文件是一个class文件,否则JVM就认为这不是class文件,也不会加载
接着两个字节表示最大的版本号和最小的版本号,从最初的Java到Java8的版本范围是45.3~53.0
magic = ca fe ba be
minor version = 0 # 最小版本
major version = 53 # 最大版本
也就是说前6个字节表示这个class文件的基本头信息,JVM在加载这个class文件时会检查是否符合这个条件
类可以使用的修饰符
普通类(外部类):public default abstract final
内部类:
- 成员内部类:public default protected private abstract final
- 局部内部类:default abstract final
- 静态内部类:public default protected private abstract final
总结:default,final时所有类类型都可以使用的;除了局部内部类,public是所有类类型都可以使用的;静态内部类,成员内部类作为内部类的两种形式可以使用所有的访问修饰符和abstract,final
只有外部类和静态内部类可以有main方法(psvm),所以这两种类类型可以运行main方法
方法总长度和行数限制
Java中一个方法编译后的字节码最长是2^32 个字节,也就是4GB的代码长度,但是由于行数的限制(行数长度只有两个字节2^16),实际上整个Java源码的长度只有64KB,这里不是说Java源码只能有64K,而是编译后的字节码长度不能超过64K
一个Java源码中的行总数最多只能有65536行,而字节码的总字节数也只能有65536个
64KB = 65536B/1024
Javap生成class文件的方式
通过Javap生成class文件命令如下
javap -verbose Message>message.txt
表示输出Message类的class信息到message.txt文件中