
CLINIT vs JVM Assemble "JASMIN"
A class or interface has at most one class or interface initialization method and is initialized (§5.5) by invoking that method. The initialization method of a class or interface has the special name <clinit>, takes no arguments, and is void (§4.3.3).
Other methods named <clinit> in a class file are of no consequence. They are not class or interface initialization methods. They cannot be invoked by any Java Virtual Machine instruction and are never invoked by the Java Virtual Machine itself.
具體翻譯見文章
http://www.itdecent.cn/p/7985df51017a
上邊兩段話大概意思是,JAVA 的類或接口最多只有一個(gè)clinit 方法(interface initialization method),而且這個(gè)方法必須無參,返回值為void,其他任務(wù)名字為clinit的方法都將被忽略。
In a class file whose version number is 51.0 or above, the method must additionally have its ACC_STATIC flag (§4.6) set in order to be the class or interface initialization method.
這段話說明在不同版本下是否需要ACC_STATIC(static)標(biāo)記
e文基本搞懂了,如何驗(yàn)證翻譯的對不對?
文章里說了,clinit方法非java源代碼的關(guān)鍵字,通過源代碼是無法驗(yàn)證的。
所以只能通過jvm匯編來實(shí)現(xiàn)。
第一種驗(yàn)證方式通過asm hardcode來驗(yàn)證,代碼已經(jīng)附在
http://www.itdecent.cn/p/7985df51017a第二種通過jvm匯編代碼來驗(yàn)證.
而我們所知的jvm 匯編器,sun官方是沒有提供的,通過javap 可以反匯編,但不能修改匯編代碼
緣于《基于JVM的匯編語言》一書,找到j(luò)asmin 項(xiàng)目。down下來源碼,源碼已經(jīng)是2000年左右的代碼,基于ant編譯,筆者將源代碼改成maven項(xiàng)目,提交到github上
https://github.com/sparrowzoo/sparrow-jasmin
項(xiàng)目的文檔及demo都到項(xiàng)目中
有興趣的同學(xué)可以fork。
另附 clinit 方法執(zhí)行順序
package com.sparrow.jdk.clinit;
public class Main {
static {
System.out.println("static init");
}
private static int i=initInt(1);
private static int j=initInt(2);
//java 源碼中static 可以出現(xiàn)多次
static {
System.out.println("static init 2");
}
private static Integer initInt(int i){
System.out.println("static field init"+i);
return 100;
}
public static void main(String[] args) {
System.out.println("main method ");
}
}