`
zhb8015
  • 浏览: 397209 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
Group-logo
Spring Roo杂谈
浏览量:0
社区版块
存档分类
最新评论

字节码学习(转)

    博客分类:
  • java
阅读更多

一直在学习Java,碰到了很多问题,碰到了很多关于i++和++i的难题,以及最经典的String str = "abc" 共创建了几个对象的疑难杂症。 知道有一日知道了java的反汇编 命令  javap。现将学习记录做一小结,以供自己以后翻看。如果有错误的地方,请指正

1.javap是什么:

 

 where options include:
-c Disassemble the code
-classpath <pathlist> Specify where to find user class files
-extdirs <dirs> Override location of installed extensions
-help Print this usage message
-J<flag> Pass <flag> directly to the runtime system
-l Print line number and local variable tables
-public Show only public classes and members
-protected Show protected/public classes and members
-package Show package/protected/public classes
and members (default)
-private Show all classes and members
-s Print internal type signatures
-bootclasspath <pathlist> Override location of class files loaded
by the bootstrap class loader
-verbose Print stack size, number of locals and args for met
hods
If verifying, print reasons for failure 

以上为百度百科里对它的描述,只是介绍了javap的一些参数和使用方法,而我们要用的就是这一个:-c Disassemble the code。

明确一个问题:javap是什么?网上有人称之为 反汇编器,可以查看java编译器为我们生成的字节码。通过它,我们可以对照源代码和字节码,从而了解很多编译器内部的工作。

2.初步认识javap

从一个最简单的例子开始:

 

 这个例子中,我们只是简单的声明了两个int型变量并赋上初值。下面我们看看javap给我们带来了什么:(当然执行javap命令前,你得首先配置好自己的环境,能用javac编译通过了,即:javac TestJavap.java )

我们只看(方便起见,将注释写到每句后面)

  Code:
   0:   iconst_2
    //把2放到栈顶
   1:   istore_1    //把栈顶的值放到局部变量1中,即i中
   2:   iconst_3    //把3放到栈顶
   3:   istore_2    //把栈顶的值放到局部变量1中,即j中
   4:   return

 

是不是很简单?(当然,估计需要点数据结构的知识) ,那我们就补点java的关于堆栈的知识:

对于 int i = 2;首先它会在栈中创建一个变量为i的引用,然后查找有没有字面值为2的地址,没找到,就开辟一个存放2这个字面值的地址,然后将i指向2的地址。

看了这段话,再比较下上面的注释,是不是完全吻合?

为了验证上面这一说法,我们继续实验:

我们将 i 和 j的值都设为2。按照以上理论,在声明j的时候,会去栈中招有没有字面值为2的地址,由于在栈中已经有2这个字面值,便将j直接指向2的地址。这样,就出现了i与j同时均指向2的情况。

 拿出javap -c进行反编译:结果如下:

  Code:
   0:   iconst_2    //把2放到栈顶
   1:   istore_1    //把栈顶的值放到局部变量1中,即i中
   2:   iconst_2    //把2放到栈顶
   3:   istore_2    //把栈顶的值放到局部变量2中,即j中(i 和 j同时指向2)
   4:   return

 

虽然这里说i和j同时指向2,但这里不等于说i和j指向同一块地址(java是不允许程序员直接修改堆栈中的数据的,所以就不要想着,我是不是可以修改栈中的2,那样岂不是i和j的值都会变化。另:在编译器内部,遇到j=2;时,它就会重新搜索栈中是否有2的字面值,如果没有,重新开辟地址存放2的值;如果已经有了,则直接将j指向这个地址。因此,就算j另被赋值为其他值,如j=4,j值的改变不会影响到i的值。)

再来一个例子:

还是javap -c

  Code:
   0:   iconst_2    //把2放到栈顶
   1:   istore_1    //把栈顶的值放到局部变量1中,即i中
   2:   iload_1     //把i的值放到栈顶,也就是说此时栈顶的值是2
   3:   istore_2    //把栈顶的值放到局部变量2中,即j中
   4:   return

看到这里是不是有点明确了?

 

 

既然我们对javap有了一定的了解,那我们就开始用它来解决一些实际的问题:

1.i++和++i的问题

反编译结果为

 Code:
  0:   iconst_1
  1:   istore_1
  2:   iinc    1, 1 //这个个指令,把局部变量1,也就是i,增加1,这个指令不会导致栈的变化,i此时变成2了
  5:   iconst_1
  6:   istore_2
  7:   iinc    2, 1//这个个指令,把局部变量2,也就是j,增加1,这个指令不会导致栈的变化,j此时变成2了
  10:  return

 

可以看出,++在前在后,在这段代码中,没有任何不同。

我们再看另一段代码:

反编译结果:

  Code:
   0:   iconst_1
   1:   istore_1
   2:   iload_1
   3:   iinc    1, 1  //局部变量1(即i)加1变为2,注意这时栈中仍然是1,没有改变
   6:   istore_1    //把栈顶的值放到局部变量1中,即i这时候由2变成了1
   7:   iconst_1
   8:   istore_2
   9:   iinc    2, 1 //局部变量2(即j)加1变为2,注意这时栈中仍然是1,没有改变
   12:  iload_2    //把局部变量2(即j)的值放到栈顶,此时栈顶的值变为2
   13:  istore_2   //把栈顶的值放到局部变量2中,即j这时候真正由1变成了2
   14:  return

是否看明白了? 如果这个看明白了,那么下面的一个问题应该就是迎刃而解了:

m = m ++;这句话,java虚拟机执行时是这样的: m的值加了1,但这是栈中的值还是0, 马上栈中的值覆盖了m,即m变成0,因此不管循环多少次,m都等于0。

如果改为m = ++m; 程序运行结果就是100了。。。

 

分享到:
评论

相关推荐

    汉字编码转换为字节码工具

    本工具就是针对这一需求而设计的,帮助用户轻松地完成汉字到字节码的转换过程。 首先,我们来了解一下汉字编码的基本概念。汉字编码主要包括以下几种类型: 1. **GB2312**:中国国家标准简体中文字符集,包含6763...

    cglib,字节码生成库是生成和转换Java字节码的高级API。它被aop、测试、数据访问框架用来生成动态代理对象和拦截字段访问。.zip

    **CGlib:高级Java字节码生成库** CGlib(Code Generation Library)是一个强大的高性能的代码生成库,它主要用于在运行期扩展Java类与实现Java接口。这个库最初由Evan Schooler创建,后来成为Apache软件基金会的一...

    java字节码文件查看工具,查看class文件

    Java字节码文件查看工具,如JD-GUI,是开发者们深入理解Java应用程序内部机制的重要辅助工具。这类工具能够帮助我们查看并分析.class文件,这些文件是Java源代码经过编译后的二进制形式,包含了运行时所需的所有指令...

    Lua字节码分析工具

    字节码分析工具,如“Lua字节码分析工具”,对于理解lua程序的运行机制、调试和优化有着重要作用。 该工具本身是用Lua编写的,这展示了Lua语言的自我解释性——即 Lua 可以用来解析和处理 Lua 代码。这种特性使得...

    java字节码文件反编译

    然而,有时我们需要查看这些字节码以进行调试、逆向工程或学习目的,这时就需要用到字节码反编译工具,如`jd-gui`。 `jd-gui`是一款开源的Java字节码反编译器,它提供了一个图形用户界面(GUI),可以方便地查看和...

    Java字节码反编译

    Java字节码反编译是Java开发者在进行代码分析、逆向工程或学习类库源码时常用的一种技术。它允许我们将已经编译过的.class文件转换回可读性更强的.java源代码文件,以便理解程序的运行逻辑。在这个过程中,我们通常...

    字节码查看器.rar

    通过它,开发者可以查看类文件的结构,包括类名、接口、字段、方法等信息,同时还能看到字节码指令的具体序列,这对于理解和优化代码、调试问题、学习JVM内部工作原理都大有裨益。 使用字节码查看器,我们可以做...

    java .net 反编译工具 字节码反编译

    Java和.NET平台都提供了各自的字节码语言,即Java字节码和.NET的MSIL(Microsoft Intermediate Language),它们是编译后的代码形式,对于源代码不可见。本文将详细探讨Java和.NET的反编译工具以及字节码反编译的...

    ASM操作字节码,动态生成Java类class文件

    ASM是一个开源的Java字节码操控和分析框架,它能够用来动态生成类或者增强已有类的功能。ASM可以被用来创建Java代理、实现元编程、甚至...在学习和使用ASM时,理解Java字节码规范以及如何映射到ASM的API是非常重要的。

    [字节码系列]ObjectWeb ASM构建Method Monitor

    【字节码系列】ObjectWeb ASM构建Method Monitor 在Java世界中,字节码是运行在JVM(Java虚拟机)上的程序表示形式。它是一种中间语言,允许开发者对Java代码进行低级别的操作,比如性能优化、动态代理、代码混淆等...

    java 反编译 字节码 源代码 绿色软件 直接打开jar包

    本文将围绕“Java反编译、字节码和源代码”这一主题,详细介绍如何使用绿色软件来查看和生成源码,以及如何直接打开.jar包。 首先,让我们理解一下Java的编译过程。在Java中,源代码(.java文件)被JDK的javac...

    java注解_反射_字节码_类加载机制.zip

    Java注解、反射、字节码和类加载机制是Java编程中的核心概念,它们在实际开发中扮演着重要角色。让我们深入探讨这些知识点。 **Java注解(Annotation)**: Java注解是一种元数据,它提供了在编译时或运行时处理代码的...

    深入字节码 -- 玩转 ASM-Bytecode1

    标题中的“深入字节码 -- 玩转 ASM-Bytecode1”暗示了本文将探讨如何使用ASM库来操作和理解Java字节码。ASM是一个Java字节码操控和分析框架,它允许用户动态生成和修改Java类和注解。在描述中提到,前一篇博文中介绍...

    java字节码反编译工具

    Java字节码反编译工具是开发者们在研究或调试Java程序时常用的一种辅助软件,它能够将已编译的Java字节码(.class文件)转换回可读性较高的源代码形式。这样的工具使得开发者可以查看和理解第三方库或者无法获取源代码...

    Recaf一个现代Java字节码编辑器

    **Recaf:现代Java字节码编辑器** 在Java开发领域,字节码编辑器是一种不可或缺的工具,它允许开发者查看、分析并修改Java类文件的字节码,从而实现对程序运行时行为的深入控制。Recaf是这样一个现代、用户友好的...

    字节码反编译软件稳定版

    字节码反编译软件如"字节码反编译软件稳定版",是开发者用来查看和理解Java字节码的工具,这对于调试、逆向工程以及学习Java虚拟机(JVM)的工作原理非常有用。以下将详细阐述字节码、反编译过程、jd-gui工具及其在...

    Java字节码和asm入门资料

    在深入学习Java字节码和ASM之前,我们需要先理解Java编译和运行的基本过程。 1. **Java编译过程**: 当我们编写Java源代码(.java文件)后,Java编译器(javac)将这些源代码转换为字节码(.class文件)。字节码是...

    Java虚拟机字节码.zip

    Java虚拟机字节码技术是Java编程中的核心概念,它涉及到程序的运行方式以及如何与Java虚拟机(JVM)交互。ASM框架是这个领域的一个关键工具,它提供了一种低级别的字节码操作能力,使得开发者能够进行深度的代码分析...

    java字节码文件反编译器

    Java字节码文件反编译器是一款非常实用的工具,主要针对Java开发者或者逆向工程爱好者,用于查看和理解已编译的Java类文件。在Java编程中,源代码会被编译成字节码(.class文件),这些字节码是机器不可读的二进制...

Global site tag (gtag.js) - Google Analytics