前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >写了那么多 Java 代码,却不一定见过它的真面目

写了那么多 Java 代码,却不一定见过它的真面目

作者头像
刘水镜
发布2022-07-29 13:24:56
2220
发布2022-07-29 13:24:56
举报
文章被收录于专栏:做个开发者

我们都知道那句著名的宣传语——「一次编写, 到处运行(Write Once, Run Anywhere)」,这是对 Java 平台无关性的精准概括。字节码 + JVM 使其平台无关,与此同时也衍生出另一个无关性——语言无关性。像 Kotlin、Groovy、Scala、Clojure、JRuby 等语言都可以运行在 JVM 之上。理论上只要能将源代码编译成符合 JVM 规范的字节码,任何语言都可以在 JVM 中运行。

字节码是连接语言和 JVM 的关键桥梁,今天我们就一起聊聊这个关键人物。

概览

我们创建一个 User 类:

代码语言:javascript
复制
 package com.shuijing;

 public class User {
 }

然后通过 javac 命令编译,得到 User.class 文件。然后用支持十六进制的文本工具(比如 sublime)打开,你会看到如下内容:

Class 十六进制

在一堆看似毫无规律的字符中,我们发现开头几个字好像有什么特别的含义——cafe babe,咖啡宝贝?没错,这也解释了为啥 Java 的商标是一杯冒着热气的咖啡。开头这四个字节叫做魔数(Magic Number),它的唯一作用就是确定这是一个可以被 JVM 接受的 Class 文件。

Class 文件中没有任何分隔符, 各数据项严丝合缝依次排列。哪个字节代表什么含义,谁挨着谁,长度是多少,都是有规定的,不能改变。

类文件结构

先来看一个 Class 文件的标准结构:

代码语言:javascript
复制
ClassFile {
  u4               magic;
  u2               minor_version;
  u2               major_version;
  u2               constant_pool_count;
  cp_info          constant_pool[constant_pool_count-1];
  u2               access_flags;
  u2               this_class;
  u2               super_class;
  u2               interfaces_count;
  u2               interfaces[interfaces_count];
  u2               fields_count;
  field_info       fields[fields_count];
  u2               methods_count;
  method_info      methods[methods_count];
  u2               attributes_count;
  attribute_info   attributes[attributes_count];
}

来自《The Java Virtual Machine Specification》Java SE 8 Edition

如上所示,Class 文件中包含两种数据类型:「无符号数」和「表」。

无符号数是基本类型,u1、 u2、 u4、 u8 分别表示 1 个字节、 2 个字节、 4 个字节和 8 个字节的无符号数。无符号数可以描述数字、索引引用、数量值或者按照 UTF-8 编码的字符串。

是由多个无符号数或其他表组合而成(复杂对象),并且以「_info」结尾。一个 Class 文件可以视作一张表。

各数据项说明:

名称

类型

数量

说明

magic

u4

1

魔数:CAFE BABE

minor_version

u2

1

次版本

major_version

u2

1

主版本

constant_pool_count

u2

1

常量池计数

constant_pool

cp_info

constant_pool_count - 1

常量池

access_flags

u2

1

访问标志

this_class

u2

1

类索引

super_class

u2

1

父类索引

interfaces_cout

u2

1

接口索引计数

interfaces

u2

interfaces_count

接口索引集合

fields_count

u2

1

字段计数

fields

field_info

fields_count

字段集合

methods_count

u2

1

方法计数

methods

method_info

methods_count

方法集合

attributes_count

u2

1

属性计数

attributes

attribute_info

attributes_count

属性集合

顺序由上到下,严格限制,不可修改

下面用一张更形象的图展示一下 Class 文件的结构示意:

Class 文件结构示意

如何查看

我们可以通过 JDK 自带的「javap」命令来查看 Class 文件的字节码信息:

代码语言:javascript
复制
 javap -v User.class

你会看到如下信息:

通过命令查看字节码

另外,还可以通过 IDEA 的插件来查看,会更加友好一些。效果如下:

通过插件查看字节码

插件:JClassLib

结束

学习字节码会让之前只知其然的知识,变得知其所以然。

今天先开(挖)个小(大)头(坑),如果你对字节码感兴趣可以留言告诉我,后面我们再进行详(慢)细(慢)讨(填)论(坑)。

- 完 -

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 做个开发者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概览
  • 类文件结构
  • 如何查看
  • 结束
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档