一、什么是字节码
1. 先来说一下什么是机械码
机械码就是cpu能够直接读取并运行的代码,它是用二进制编码表示的,也叫做机械指令码。在编写这种代码时,需要主动地去控制cpu的一切资源,而且需要记住全部指令所做的动作,十分的麻烦,当然这也是计算机的底层代码,处理开发计算机的专业人员之外,已经很少人去研究了。
2.字节码
字节码是一种中间状态的二进制文件,是由源码编译过来的,可读性没有源码的高。cpu并不能直接读取字节码,在java中,字节码需要经过JVM转译成机械码之后,cpu才能读取并运行。
3.使用字节码的好处
一处编译,到处运行。java就是典型的使用字节码作为中间语言,在一个地方编译了源码,拿着.class文件就可以在各种计算机运行,每个计算机上的jvm就会有所不同了。
4.字节码在JVM中的状态
5.额外提一点
编译型语言
只需要编译一次,就能够将源代码编译成机械码。执行效率高,可移植性低,依赖编译器。
典型代表:C、C++、Pascal、Object-C以及最近很火的苹果新语言swift,GO
解释型语言
在第一次编译时,并不会直接将源代码编译成机械码,而是编译成一种中间状态的二进制文件(字节码),由虚拟机来对这个二进制文件进行第二次编译,这次才是编译成机械码。执行效率比编译型语言低,但是可移植性高,依赖虚拟机。
典型代表:JavaScript、Python、Erlang、PHP、Perl、Ruby
二、java中的字节码
1.查看字节码的方式
- 首先打开idea,在里面创建一个.java文件
package test;
public class ByteCodeTest {
private int a = 0;
public int get() {
return a;
}
}
然后在另一个类上,运行main方法,调用这个类
-
找到编译后的.class文件
out文件夹下面会多出一个我们刚刚编写的java文件相同名称的.class文件
- 下载一个Sublime Text,然后打开.class文件
cafe babe 0000 0034 0016 0a00 0400 1209
0003 0013 0700 1407 0015 0100 0161 0100
0149 0100 063c 696e 6974 3e01 0003 2829
5601 0004 436f 6465 0100 0f4c 696e 654e
756d 6265 7254 6162 6c65 0100 124c 6f63
616c 5661 7269 6162 6c65 5461 626c 6501
0004 7468 6973 0100 134c 7465 7374 2f42
7974 6543 6f64 6554 6573 743b 0100 0367
6574 0100 0328 2949 0100 0a53 6f75 7263
6546 696c 6501 0011 4279 7465 436f 6465
5465 7374 2e6a 6176 610c 0007 0008 0c00
0500 0601 0011 7465 7374 2f42 7974 6543
6f64 6554 6573 7401 0010 6a61 7661 2f6c
616e 672f 4f62 6a65 6374 0021 0003 0004
0000 0001 0002 0005 0006 0000 0002 0001
0007 0008 0001 0009 0000 0038 0002 0001
0000 000a 2ab7 0001 2a03 b500 02b1 0000
0002 000a 0000 000a 0002 0000 0003 0004
0004 000b 0000 000c 0001 0000 000a 000c
000d 0000 0001 000e 000f 0001 0009 0000
002f 0001 0001 0000 0005 2ab4 0002 ac00
0000 0200 0a00 0000 0600 0100 0000 0600
0b00 0000 0c00 0100 0000 0500 0c00 0d00
0000 0100 1000 0000 0200 11
2.一个疑惑
我也希望有大佬能够解答一下我疑惑,我去查百度也找不到答案,可能是我搜索方式有问题。
上面是.class文件的十六进制形式
在idea中有这样一个功能,view->Show ByteCode
用这个功能打开的是
// class version 52.0 (52)
// access flags 0x21
public class test/ByteCodeTest {
// compiled from: ByteCodeTest.java
// access flags 0x2
private I a
// access flags 0x1
public <init>()V
L0
LINENUMBER 3 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
L1
LINENUMBER 4 L1
ALOAD 0
ICONST_0
PUTFIELD test/ByteCodeTest.a : I
RETURN
L2
LOCALVARIABLE this Ltest/ByteCodeTest; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
// access flags 0x1
public get()I
L0
LINENUMBER 6 L0
ALOAD 0
GETFIELD test/ByteCodeTest.a : I
IRETURN
L1
LOCALVARIABLE this Ltest/ByteCodeTest; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
}
我想知道这个跟十六进制文件的区别是什么?
它们俩是怎么转换的?
——————————————————————————————
如果本文章内容有问题,请直接评论或者私信我。
未经允许,不得转载!