Java 中引入了虚拟机的观点,即在机器和编译程序之间加入了一层抽象的虚拟的机器。
这台虚拟的机器在任何平台上都供应给编译程序一个的共同的接口。

编译程序只须要面向虚拟机,天生虚拟机能够理解的代码,然后由阐明器来将虚拟机代码转换为特定系统的机器码实行。
在 Java 中,这种供虚拟机理解的代码叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。

随便找一个项目汇总的.class文件,然后利用16进制的方法查看:

字节码php面试官什么是字节码它最年夜的优势是什么 GraphQL

0000000:cafebabe0000003400610a0016004709.......4.a....G.0000010:000500480900050049090005004a0700...H....I....J..0000020:4b0a0005004c0a0005004d0a0016004eK....L....M....N0000030:0a0005004f0a000500500a0016005107....O....P....Q.0000040:00520a000c00470800530a000c00540a.R....G..S....T.0000050:000c00550800560800570a000c005808...U..V..W....X.0000060:00590a000c005a07005b07005c010005.Y....Z..[..\...0000070:74616749640100134c6a6176612f6c61tagId...Ljava/la0000080:6e672f496e74656765723b0100077461ng/Integer;...ta0000090:674e616d650100124c6a6176612f6c61gName...Ljava/la00000a0:6e672f537472696e673b010005746f74ng/String;...tot00000b0:616c010001490100063c696e69743e01al...I...<init>.00000c0:0003282956010004436f646501000f4c..()V...Code...L00000d0:696e654e756d6265725461626c650100ineNumberTable..00000e0:124c6f63616c5661726961626c655461.LocalVariableTa00000f0:626c650100047468697301001f4c636fble...this...Lco0000100:6d2f6a6176612f7469616e2f626c6f67m/java/tian/blog0000110:2f656e746974792f5461673b01000867/entity/Tag;...g0000120:6574546167496401001528294c6a6176etTagId...()Ljav0000130:612f6c616e672f496e74656765723b01a/lang/Integer;.0000140:000a6765745461674e616d6501001428..getTagName...(0000150:294c6a6176612f6c616e672f53747269)Ljava/lang/Stri0000160:6e673b010008676574546f74616c0100ng;...getTotal..0000170:03282949010008736574546167496401.()I...setTagId.0000180:0016284c6a6176612f6c616e672f496e..(Ljava/lang/In0000190:74656765723b29560100104d6574686fteger;)V...Metho00001a0:64506172616d657465727301000a7365dParameters...se00001b0:745461674e616d65010015284c6a6176tTagName...(Ljav00001c0:612f6c616e672f537472696e673b2956a/lang/String;)V00001d0:010008736574546f74616c0100042849...setTotal...(I00001e0:2956010006657175616c73010015284c)V...equals...(L00001f0:6a6176612f6c616e672f4f626a656374java/lang/Object0000200:3b295a0100016f0100124c6a6176612f;)Z...o...Ljava/0000210:6c616e672f4f626a6563743b0100056flang/Object;...o0000220:7468657201000a746869732474616749ther...this$tagI0000230:6401000b6f7468657224746167496401d...other$tagId.0000240:000c74686973247461674e616d650100..this$tagName..0000250:0d6f74686572247461674e616d650100.other$tagName..0000260:0d537461636b4d61705461626c650700.StackMapTable..0000270:4b07005b01000863616e457175616c01K..[...canEqual.0000280:000868617368436f6465010005505249..hashCode...PRI0000290:4d45010006726573756c740100062474ME...result...$t00002a0:61674964010008247461674e616d6501agId...$tagName.00002b0:0008746f537472696e6701000a536f75..toString...Sou00002c0:72636546696c650100085461672e6a61rceFile...Tag.ja00002d0:76610c001e001f0c001800190c001a00va..............00002e0:1b0c001c001d01001d636f6d2f6a6176.........com/jav00002f0:612f7469616e2f626c6f672f656e7469a/tian/blog/enti0000300:74792f5461670c003e00330c00250026ty/Tag..>.3..%.&0000310:0c003200330c002700280c0029002a0c..2.3..'.(..)..0000320:003f002a0100176a6176612f6c616e67.?....java/lang0000330:2f537472696e674275696c6465720100/StringBuilder..0000340:0a5461672874616749643d0c005d005e.Tag(tagId=..].^0000350:0c005d005f01000a2c207461674e616d..]._...,tagNam0000360:653d0100082c20746f74616c3d0c005de=...,total=..]25linesfiltered

查看办法是先利用vim将.class文件打开,然后输入:%!xxd然后就可以看到cafe babe开头的字节码了。

其余一种办法查看字节码的办法:xxd Tag.class Tag.txt和上面一样。

二进制与16进制转换还有其他一些办法,如下:

以十六进制格式输出:od [选项] 文件od -d 文件 十进制输出-o 文件 八进制输出-x 文件 十六进制输出xxd 文件 输出十六进制

在vi命令状态下::%!xxd :%!od 将当前文本转化为16进制格式:%!xxd -c 12 每行显示12个字节:%!xxd -r 将当前文本转化回文本格式

上面的字节码看起来是不是很无语,很多人是对其很厌烦。
实在也没那么难的。

每一种平台的阐明器是不同的,但是实现的虚拟机是相同的。
Java 源程序经由编译器编译后变成字节码,字节码由虚拟机阐明实行,虚拟机将每一条要实行的字节码送给阐明器,阐明器将其翻译成特定机器上的机器码,然后在特定的机器上运行。
这也便是阐明了 Java 的编译与阐明并存的特点。

Java源代码=>编译器=>JVM可实行的Java字节码(即虚拟指令)=>JVM=>JVM中阐明器=>机器可实行的二进制机器码=>程序运行采取字节码的好处?

Java 措辞通过字节码的办法,在一定程度上办理了传统阐明型措辞实行效率低的问题,同时又保留理解释型措辞可移植的特点。
以是 Java 程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的打算机上运行。

阐明型措辞:阐明型措辞,是在运行的时候将程序翻译成机器措辞。
阐明型措辞的程序不须要在运行前编译,在运行程序的时候才翻译,专门的阐明器卖力在每个语句实行的时候阐明程序代码。
这样阐明型措辞每实行一次就要翻译一次,效率比较低。
——百度百科

例如:Python、PHP 。