Java为什么能够支持跨平台,其实关键就是在于其*.class字节码文件,因为*.class字节码文件有一个统一标准的规范,里面是JVM运行的时需要的相关指令,各家的JVM必须能够解释编译执行标准字节码文件,因此Java是一种跨平台语言,再想想C++/C等语言为什么不是跨平台的,就是因为其源文件经过编译后生成的就是针对特定机器的汇编代码

字节码文件解析

在解析之前最好下载一个工具方便查看(Bytecode viewer),当然也可以不用下载,直接使用JDK自带的命令如javap –c –s –l –verbose (字节码文件去掉扩展名)

一个简单的程序

public class Test {
private static final int MAX_COUNT=1000;
private static int count=0;
public int bar() throws Exception{
if(++count>=MAX_COUNT){
count=0;
throw new Exception("count overflow");
}
return count;
}
}

运行工具软件查看得下图:

看到了吧,一个字节码文件由6部份组成,先看第一部份General Information,这一部份中说明了JDK使用的版本号Major version=51表示使用的是JDK 7,Minor version=0表示的是次版本号,这也限制了运行此字节码文件需要的最低JDK版本号,不信你可以试试下面这条语句,其实就是从字节码文件中获取到class的版本号

System.out.println(System.getProperty("java.class.version"));

下面是constant pool=35,常量池中存放着类中定义的所有常量,大致包括类名,方法名,特征符以及字符串等,Access flag=0x0021[public]表识该类的访问权限,This class=cp_info_#1<Test>其中cp是const pool的缩写,表示这个类的信息保存在了1号常量池中,下面讲到constant pool时再说,super class=cp_info_#3也表示同一个意思,Interface count=0表示类没有实现接口,Fields count=2说明类中定义了两个成员变量,不信你看看刚才的源文件是不是有两个变量,Methods count=3表明类中定义的方法数是3(clinit对静态变量进行赋值由JVM调用, init为类的构造函数 bar用户自定义函数),Attribute count=1表示是类格式属性看看常量池如下,不截图了

[01] CONSTANT_Class_info
Classname:cp_info_#2<Test>
表示Classname存放在2号常量池中
[02] CONSTANT_Utf8_info
Length of byte array :4
Length of string:4
String: Test

表示类名是Test,长度是4,占用4个字节

其他类似,看看方法Method里的<init>即构造函数

Name: cp_info_#17<<init>>
Desciptor:cp_info_#11<()V>
Access flags:0x0001[public]

Name的信息在常量池cp_info_#17中

Length of byte array:6
Length of string:6
String:<init>

从中可以看出其定义了字节码中类的构造函数的方法名,Descriptor描述的是函数的返回类型

Length of byte array:3
Length of string:3
String:()V

描述了函数的返回类型即为void类型,这个Access flags就不用多说了吧,表示的是函数访问权限,缺省构造器中的“指令是面向过程的汇编语言。aload_0说的是把对象的引用保存到JVM的0号局部变量,并且把它压入栈。invokespecial #1这条命令是调用java.lang.Object中的构造(这些信息保存在1号常量项里,好处是减少字节码的长度),return是执行完毕退出的意思。Bar函数的分析类似,其字节码文件对应的指令如下

getstatic #13<Test.count>
iconst_1
iadd
dup
putstatic #13<Test.count>
sipush 1000
if_icmplt 29(+17)
iconst_0
putstatic #13<Test.count>
new #25
dup
ldc #27<count overflow>
invokespecial #29<java/lang/Exception.<init>>
athrow
getstatic #13<Test.count>
ireturn

[置顶] Java字节码文件剖析的更多相关文章

  1. JAVA字节码文件之结构

    开发工具:IEDA.JDK1.8.WinHex 一.字节码文件结构 源代码 package com.jalja.java.bytecode; /** * @Auther: XL * @Date: 20 ...

  2. JAVA字节码文件之第三篇(访问标识)

    一.Access Flags 访问标志 访问标志信息包括该 Class 文件是类还是接口,是否被定义成 public 或者 abstract , 如果是类,是否被声明成 final. 访问标志表 二. ...

  3. JAVA字节码文件之第四篇(方法分析)

    一.Methods 方法字节码结构 Methods 字节码结构: Methods num:占两byte,Methods 的具体内存占n个byte 方法中每个属性都是Attribute_info,Att ...

  4. JAVA字节码文件之常量池

    一.常量池的内容 一个java类中定义的很多信息都是由常量池来维护和描述的,可以将常量池看作是class文件的资源仓库,比如java类中定义的方法与变量信息.常量池中主要存储两类常量:字面量(文本字符 ...

  5. 命令行中运行Java字节码文件提示找不到或无法加载主类的问题

    测试类在命令行操作,编译通过,运行时,提示 错误: 找不到或无法加载主类 java类 package com.company.schoolExercise; public class test7_3_ ...

  6. 【JVM故事】一个Java字节码文件的诞生记

    万字长文,完全虚构. (一) 组里来了个实习生,李大胖面完之后,觉得水平一般,但还是留了下来,为什么呢?各自猜去吧. 李大胖也在心里开导自己,学生嘛,不能要求太高,只要肯上进,慢慢来.就称呼为小白吧. ...

  7. 【java】查看Java字节码文件内容的方法+使用javap找不到类 解决方法

    研究synchronized底层实现,涉及到查看java字节码的需要 前提是,你的PC已经成功安装了JDK并别配置了环境变量. ==========查看方法========= 一.javap查看简约字 ...

  8. java字节码文件指令集

    网上找的没有指令码这列  自己把它加上 更方便查阅 指令从0x00-0xc9 没有0xba 常量入栈指令 指令码 操作码(助记符) 操作数 描述(栈指操作数栈) 0x01 aconst_null nu ...

  9. Java字节码深度剖析

    Java字节码文件查看 我们有一个类Test01,具体内容如下: package bytecode; public class Test01 { private int i = 0; public i ...

随机推荐

  1. iOS8的屏幕旋转的问题

    判断横竖屏.http://www.cocoachina.com/ask/questions/show/121301 //self.cameraView是相机view - (NSUInteger)sup ...

  2. C# MVC 自学笔记—4 添加视图

    ==============================翻译============================== 在本节中,你将要修改 HelloWorldController 类,以便使 ...

  3. objective-C 初识

    objective-C objective-c 是c语言的改进版 一.方法的定义: 格式: -/+(返回值类型)方法名:(参数类型) 参数名 [方法名] : (参数类型) 参数名......... 例 ...

  4. ListView属性解释

    1.android:scrollbarStyle 定义滚动条的样式和位置 参考:http://www.trinea.cn/android/android-scrollbarstyle/ 2.andro ...

  5. 树莓派linux驱动学习之hello world

    最近想学习一下linux驱动,看了一些书和教学视频,大概了解了一下,不过要想深入,肯定需要实践.手上有几块linux的板子,最终选择了树莓派作为我的实验平台,资料比较丰富,接口也比较简单. 程序员的入 ...

  6. [转]linux下iftop工具的安装与使用详解(图文)——实时的网络流量,监控TCP/IP连接(单机)

    原文链接:http://www.jbxue.com/LINUXjishu/10735.html 在linux中监控系统资源.进程.内存占用等信息,可以使用top命令.查看网络状态可以使用netstat ...

  7. OAuth2.0认证过程

    本文以腾讯微博为例,详细介绍OAuth2.0的认证过程. 在使用腾讯微博平台提供的API前,您需要做以下两步工作: 成为开发者,并申请appkey和appsecret 授权获取accesstoken ...

  8. WPF4多点触摸事件

    原文 WPF4多点触摸事件 UIElement在WPF4下添加了很多支持多点触摸的事件,通过它们可以在硬件支持的情况下处理多点触摸,以下通过代码来说明通过处理这些事件,我们可以做些什么: 一.触摸相关 ...

  9. docker学习笔记4:利用docker hub上的mysql镜像创建mysql容器

    docker hub上有官方的mysql镜像,我们可以利用它来创建mysql容器,作为一个服务容器使用. 1.下载mysql镜像 docker pull mysql 2.创建镜像 docker run ...

  10. Docker学习笔记(4) — 开启Docker远程访问

    默认情况下,Docker守护进程会生成一个socket(/var/run/docker.sock)文件来进程本地进程通信,而不会监听任何端口,因此只能在本地使用docker客户端或者使用Docker ...