首先你需要了解Dalvik虚拟机以及Dalvik虚拟机和Java虚拟机的区别: 浅入Dalvik虚拟机
如果你了解了Dalvik虚拟机,那下面开始了
Hello.java文件:
public class Hello {
public static void main(String[] args){
//System.out.print("Hello");
int i=2;
int j=3;
}
}
通过javac Hello.java得到Hello.class文件
JDK中提供了javap命令反汇编可以查看class文件字节码:
javap -c Hello ->demo.txt
将Hello.class字节码中的内容存放到demo.txt中,如下:
Compiled from "Hello.java"
public class Hello {
public Hello();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_2
1: istore_1
2: iconst_3
3: istore_2
4: return
}
如上就是java字节码的内容。
可以看到.class字节码中的内容格式和Dalvik中的字节码不是一致的,不会去加载。但是Dalvik可以加载dex文件,通过dx工具可以将Hello.class文件转为dex文件:
dx --dex --output=Hello.dex Hello.class
Dalvik字节码我们无法直接查看,最终需要查看的是samli格式的文件,通过将Hello.dex文件转为smali文件,smali文件是Dalvik可以识别的核心代码,可以使用AndroidStudio自带的插件实现(或者使用baksmali也是可以的),以下就是相对应的smali文件格式:
smali有自己的一套语法,可以参考:史上超详细的smali文件解读
.class public Lcom/example/administrator/myapplication/Hello;
.super Ljava/lang/Object;
.source "Hello.java"
# direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 3
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static main([Ljava/lang/String;)V
.registers 3
.param p0, "args" # [Ljava/lang/String;
.prologue
.line 7
const/4 v0, 0x2
.line 8
.local v0, "i":I
const/4 v1, 0x3
.line 9
.local v1, "j":I
return-void
.end method
通过比较,java字节码和Dalvik字节码是不一样的,所以Android虚拟机加载的是dex字节码,而不能记载java字节码。
除了上面所说的之外,.class文件和dex文件在数据结构是不一样的!