这个问题,面试官可以衍生提问,Java 是编译执行的语言,还是解释执行的语言。
Java 中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。
编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在 Java 中,这种供虚拟机理解的代码叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。
随便找一个项目汇总的.class文件,然后使用16进制的方法查看:
0000000:cafebabe0000003400610a0016004709.......4.a....G. 0000010:000500480900050049090005004a0700...H....I....J.. 0000020:4b0a0005004c0a0005004d0a0016004eK....L....M....N 0000030:0a0005004f0a000500500a0016005107....O....P....Q. 0000040:00520a000c00470800530a000c00540a.R....G..S....T. 0000050:000c00550800560800570a000c005808...U..V..W....X. 0000060:00590a000c005a07005b07005c010005.Y....Z..[..... 0000070:74616749640100134c6a6176612f6c61tagId...Ljava/la 0000080:6e672f496e74656765723b0100077461ng/Integer;...ta 0000090:674e616d650100124c6a6176612f6c61gName...Ljava/la 00000a0:6e672f537472696e673b010005746f74ng/String;...tot 00000b0:616c010001490100063c696e69743e01al...I...<init>. 00000c0:0003282956010004436f646501000f4c..()V...Code...L00000d0:696e654e756d6265725461626c650100ineNumberTable.. 00000e0:124c6f63616c5661726961626c655461.LocalVariableTa 00000f0:626c650100047468697301001f4c636fble...this...Lco 0000100:6d2f6a6176612f7469616e2f626c6f67m/java/tian/blog 0000110:2f656e746974792f5461673b01000867/entity/Tag;...g 0000120:6574546167496401001528294c6a6176etTagId...()Ljav 0000130:612f6c616e672f496e74656765723b01a/lang/Integer;.0000140:000a6765745461674e616d6501001428..getTagName...(0000150:294c6a6176612f6c616e672f53747269)Ljava/lang/Stri0000160:6e673b010008676574546f74616c0100ng;...getTotal..0000170:03282949010008736574546167496401.()I...setTagId.0000180:0016284c6a6176612f6c616e672f496e..(Ljava/lang/In 0000190:74656765723b29560100104d6574686fteger;)V...Metho 00001a0:64506172616d657465727301000a7365dParameters...se 00001b0:745461674e616d65010015284c6a6176tTagName...(Ljav00001c0:612f6c616e672f537472696e673b2956a/lang/String;)V 00001d0:010008736574546f74616c0100042849...setTotal...(I 00001e0:2956010006657175616c73010015284c)V...equals...(L00001f0:6a6176612f6c616e672f4f626a656374java/lang/Object 0000200:3b295a0100016f0100124c6a6176612f;)Z...o...Ljava/ 0000210:6c616e672f4f626a6563743b0100056flang/Object;...o 0000220:7468657201000a746869732474616749ther...this$tagI 0000230:6401000b6f7468657224746167496401d...other$tagId. 0000240:000c74686973247461674e616d650100..this$tagName.. 0000250:0d6f74686572247461674e616d650100.other$tagName.. 0000260:0d537461636b4d61705461626c650700.StackMapTable.. 0000270:4b07005b01000863616e457175616c01K..[...canEqual. 0000280:000868617368436f6465010005505249..hashCode...PRI 0000290:4d45010006726573756c740100062474ME...result...$t 00002a0:61674964010008247461674e616d6501agId...$tagName. 00002b0:0008746f537472696e6701000a536f75..toString...Sou 00002c0:72636546696c650100085461672e6a61rceFile...Tag.ja 00002d0:76610c001e001f0c001800190c001a00va.............. 00002e0:1b0c001c001d01001d636f6d2f6a6176.........com/jav 00002f0:612f7469616e2f626c6f672f656e7469a/tian/blog/enti 0000300:74792f5461670c003e00330c00250026ty/Tag..>.3..%.& 0000310:0c003200330c002700280c0029002a0c..2.3..'.(..).*. 0000320:003f002a0100176a6176612f6c616e67.?.*...java/lang 0000330:2f537472696e674275696c6465720100/StringBuilder.. 0000340:0a5461672874616749643d0c005d005e.Tag(tagId=..].^ 0000350:0c005d005f01000a2c207461674e616d..]._...,tagNam 0000360: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 。
,
字节面试最佳时间
作者: 315
•
•
阅读:114174
什么是字节码?
赞 (6)
打赏
微信扫一扫