`
lxbfly
  • 浏览: 38291 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java字节码深入解析

    博客分类:
  • java
阅读更多

一:Java字节代码的组织形式

类文件{

OxCAFEBABE,小版本号,大版本号,常量池大小,常量池数组,访问控制标记,当前类信息,父类信息,实现的接口个数,实现的接口信息数组,域个数,域信息数组,方法个数,方法信息数组,属性个数,属性信息数组

}

二:查看方法 --- javap命令

例子:有一个Java类Demo.java

  1. public class Demo { 
  2.     private String str1; 
  3.     private String str2; 
  4.     private int num1; 
  5.     private int num2; 
  6.     public static final String STATIC_DATA = "hello world"
  7.      
  8.     private void sayHello1(){ 
  9.         System.out.println("this is method1..."); 
  10.     } 
  11.     private void sayHello2(){ 
  12.         System.out.println("this is method2..."); 
  13.     } 
  14.     public void sayHello3(){ 
  15.         System.out.println("this is method3..."); 
  16.     } 

通过jdk自带的反编译工具命令 javap 可以查看class文件的字节码信息

D:\>javap -verbose Demo >> Demo.txt

Demo.txt:

  1. Compiled from "Demo.java" 
  2. public class Demo extends java.lang.Object 
  3.   SourceFile: "Demo.java" 
  4.   minor version: 0 
  5.   major version: 49   
  6.   
  7.   Constant pool: 
  8. const #1 = class      #2;   //  Demo 
  9. const #2 = Asciz     Demo; 
  10. const #3 = class      #4;   //  java/lang/Object 
  11. const #4 = Asciz     java/lang/Object; 
  12. const #5 = Asciz     str1; 
  13. const #6 = Asciz     Ljava/lang/String;; 
  14. const #7 = Asciz     str2; 
  15. const #8 = Asciz     num1; 
  16. const #9 = Asciz     I; 
  17. const #10 = Asciz   num2; 
  18. const #11 = Asciz   STATIC_DATA; 
  19. const #12 = Asciz   ConstantValue; 
  20. const #13 = String  #14//  hello world 
  21. const #14 = Asciz   hello world; 
  22. const #15 = Asciz   <init>; 
  23. const #16 = Asciz   ()V; 
  24. const #17 = Asciz   Code; 
  25. const #18 = Method       #3.#19;   //  java/lang/Object."<init>":()V 
  26. const #19 = NameAndType    #15:#16;//  "<init>":()V 
  27. const #20 = Asciz   LineNumberTable; 
  28. const #21 = Asciz   LocalVariableTable; 
  29. const #22 = Asciz   this
  30. const #23 = Asciz   LDemo;; 
  31. const #24 = Asciz   sayHello1; 
  32. const #25 = Field   #26.#28;  //  java/lang/System.out:Ljava/io/PrintStream; 
  33. const #26 = class    #27//  java/lang/System 
  34. const #27 = Asciz   java/lang/System; 
  35. const #28 = NameAndType    #29:#30;//  out:Ljava/io/PrintStream; 
  36. const #29 = Asciz   out; 
  37. const #30 = Asciz   Ljava/io/PrintStream;; 
  38. const #31 = String  #32//  this is method1... 
  39. const #32 = Asciz   this is method1...; 
  40. const #33 = Method       #34.#36;  //  java/io/PrintStream.println:(Ljava/lang/String;)V 
  41. const #34 = class    #35//  java/io/PrintStream 
  42. const #35 = Asciz   java/io/PrintStream; 
  43. const #36 = NameAndType    #37:#38;//  println:(Ljava/lang/String;)V 
  44. const #37 = Asciz   println; 
  45. const #38 = Asciz   (Ljava/lang/String;)V; 
  46. const #39 = Asciz   sayHello2; 
  47. const #40 = String  #41//  this is method2... 
  48. const #41 = Asciz   this is method2...; 
  49. const #42 = Asciz   sayHello3; 
  50. const #43 = String  #44//  this is method3... 
  51. const #44 = Asciz   this is method3...; 
  52. const #45 = Asciz   SourceFile; 
  53. const #46 = Asciz   Demo.java; 
  54.   
  55. public static final java.lang.String STATIC_DATA; 
  56.   Constant value: String hello world 
  57. public Demo(); 
  58.   Code: 
  59.    Stack=1, Locals=1, Args_size=1 
  60.    0:      aload_0 
  61.    1:      invokespecial  #18//Method java/lang/Object."<init>":()V 
  62.    4:      return 
  63.   LineNumberTable: 
  64.    line 20 
  65.   LocalVariableTable: 
  66.    Start  Length  Slot  Name   Signature 
  67.    0      5      0    this       LDemo; 
  68.   
  69. public void sayHello3(); 
  70.   Code: 
  71.    Stack=2, Locals=1, Args_size=1 
  72.    0:      getstatic   #25//Field java/lang/System.out:Ljava/io/PrintStream; 
  73.    3:      ldc   #43//String this is method3... 
  74.    5:      invokevirtual  #33//Method java/io/PrintStream.println:(Ljava/lang/String;)V 
  75.    8:      return 
  76.   LineNumberTable: 
  77.    line 170 
  78.    line 188 
  79.   LocalVariableTable: 
  80.    Start  Length  Slot  Name   Signature 
  81.    0      9      0    this       LDemo; 

解析:

1.版本号 major version: 49 //java版本 jdk1.6显示的是50, jdk1.5显示的是49,jdk1.4显示的是58 , 高版本能执行低版本的class文件

2.常量池Constant pool

Method:方法

Field:字段

String:字符串

Asciz:签名如<init>由jvm调用,其他是不能够去调用它的

NameAndType:变量名的类型

Class:类

通过字节码,我们可以看到Demo类 继承于java.lang.Object,如果类中没有显式声明构造函数的话,编译器会插入一个缺省无参的构造函数(构造函数在JVM级别是显示成<init>的普通函数)。

三:检测代码的效率问题

学习Java的过程中,都会了解到字符串合并时要用到StringBuffer 来代替String,那下面就来通过Java字节码来验证两种方式的效率性。

例子:一个Java类 TestString.java

  1. <strong>public class TestString { 
  2.     public String testString(String str1, String str2){ 
  3.        return str1 + str2; 
  4.     } 
  5.     public String testStringBuffer(StringBuffer sb, String str){ 
  6.        return sb.append(str).toString(); 
  7.     } 
  8.  </strong> 

javap –c TestString 后字节码信息:

  1. Compiled from "TestString.java" 
  2. public class TestString extends java.lang.Object{ 
  3. public TestString(); 
  4.   Code: 
  5.    0:      aload_0 
  6.    1:      invokespecial  #8//Method java/lang/Object."<init>":()V 
  7.    4:      return 
  8.   
  9. public java.lang.String testString(java.lang.String, java.lang.String); 
  10.   Code: 
  11.    0:      new #16//class java/lang/StringBuilder 
  12.    3:      dup 
  13.    4:      aload_1 
  14.    5:      invokestatic    #18//Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
  15.    8:      invokespecial  #24//Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
  16.    11:     aload_2 
  17.    12:    invokevirtual  #27//Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
  18.    15:    invokevirtual  #31//Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
  19.    18:    areturn 
  20.   
  21. public java.lang.String testStringBuffer(java.lang.StringBuffer, java.lang.String); 
  22.   Code: 
  23.    0:      aload_1 
  24.    1:      aload_2 
  25.    2:      invokevirtual  #40//Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer; 
  26.    5:      invokevirtual  #45//Method java/lang/StringBuffer.toString:()Ljava/lang/String; 
  27.    8:      areturn 

从上面编译后的字节码信息可以看出来,方法testString 调用了五个方法:new 、invokestatic 、invokespecial 和两个invokevirtual ; 而testStringBuffer 方法只调用了两个invokevirtual 方法。第一个方法比第二个方法多做了好多工作,其效率当然是要低的。而且我们从java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

可以看出来其实对于String字符串合并,内部还是转化为StringBuilder的方法调用,这是因为String是长度不可变的,所以不如直接采用StringBuilder(与StringBuffer 长度都是可变的,只不过前者是非线程安全,后者是线程安全)进行字符串合并。

原文链接:http://15838341661-139-com.iteye.com/blog/1287866


本文地址http://www.chengxuyuans.com/javabase/33699.html

分享到:
评论

相关推荐

    从一个class文件深入理解Java字节码结构

    我们都知道,Java程序最终是转换成class文件执行在虚拟机上的,那么class文件是个怎样的结构,虚拟机又是如何处理去执行class文件里面的内容呢,这篇文章带你深入理解Java字节码中的结构。 1.Demo源码 首先,编写一...

    2021-2022年收藏的精品资料软件工程师Java字节码开发深入解析教程解释.docx

    精品教育教学资料

    深入理解java类加载机制

    我们将详细讲解字节码文件的结构、语法和格式,以及字节码指令的定义和应用,并通过大量实例进行编程详解,帮助开发人员深入了解Java字节码的使用方法和技巧。 在类加载方面,我们将深入探讨Java程序的类加载原理和...

    JVM 完整深入解析.pdf

    JVM 完整深入解析.pdf

    Java并发编程原理与实战

    从Java字节码的角度看线程安全性问题.mp4 synchronized保证线程安全的原理(理论层面).mp4 synchronized保证线程安全的原理(jvm层面).mp4 单例问题与线程安全性深入解析.mp4 理解自旋锁,死锁与重入锁.mp4 深入...

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

    3.4.3 第三趟:字节码验证 3.4.4 第四趟:符号引用的验证 3.4.5 二进制兼容 3.5 java虚拟机中内置的安全特性 3.6 安全管理器和java api 3.7 代码签名和认证 3.8 一个代码签名示例 3.9 策略 3.10...

    解析Java虚拟机开发

    虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟...Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。 [1]

    编译原理:深入解析与实践指南.pdf

    它的主要任务是将源代码(如C、Java等语言编写的程序)转换为目标代码(通常是机器语言或字节码)。编译过程大致可以分为词法分析、语法分析、语义分析、中间代码生成、优化和目标代码生成等阶段。 词法分析是编译...

    深入解析基于SSM框架的RBAC权限控制模型实战源码

    - 字节码文件:17个CLASS文件,为Java源码编译后的产物。 - 动态图片:14个GIF文件,为界面增添动态效果。 项目简述: 本项目以SSM框架为基础,结合RBAC权限控制模型,对用户角色和权限进行精细化管理。它不仅体现...

    深入Java虚拟机

    3.4.3 第三趟:字节码验证 3.4.4 第四趟:符号引用的验证 3.4.5 二进制兼容 3.5 Java虚拟机中内置的安全特性 3.6 安全管理器和Java API 3.7 代码签名和认证 3.8 一个代码签名示例 3.9 策略 3.10...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    / 259 10.2.2 解析与填充符号表 / 262 10.2.3 注解处理器 / 264 10.2.4 语义分析与字节码生成 / 264 10.3 Java语法糖的味道 / 268 10.3.1 泛型与类型擦除 / 268 10.3.2 自动装箱、拆箱与遍历循环 / 273 10.3.3...

    深入java虚拟机第二版

    3.4.3 第三趟:字节码验证 3.4.4 第四趟:符号引用的验证 3.4.5 二进制兼容 3.5 Java虚拟机中内置的安全特性 3.6 安全管理器和Java API 3.7 代码签名和认证 3.8 一个代码签名示例 3.9 策略 3.10 保护域 ...

    Java编程艺术 PDF

    1.6 通过字节码保证可移植性和安全性 5 1.7 丰富的Java API 6 1.8 Applet 7 1.9 继续变革 7 第2章 递归下降的表达式解析器 9 2.1 表达式 10 2.2 解析表达式 11 2.3 表达式的解析 11 2.4 表达式的分解 13 2.5 一个...

    HotSpot实战

    Java原先是把源代码编译为字节码在虚拟机执行,这样整体执行效率不高。而HotSpot关注的是对部分热点(hot spot)代码的动态优化,将那些频繁执行的热点代码编译为本地原生代码,这样就显著地提高了性能。

    Java虚拟机

    第三部分分析了虚拟机的执行子系统,包括类文件结构、虚拟机类加载机制、虚拟机字节码执行引擎。第四部分讲解了程序的编译与代码的优化,阐述了泛型、自动装箱拆箱、条件编译等语法糖的原理;讲解了虚拟机的热点探测...

    java8集合源码分析-java-agent:基于java5Instrumentapi实现的mock框架

    该项目就是这么做的,在jvm加载类的时候,通过字节码工具包javassist, 修改了字节码。 方法执行时,并不执行原来的代码,而是动态解析groovy代码,调用groovy方法。 我们可以在相关的groovy代码中配置哪些类的方法...

    龙果java并发编程完整视频

    第13节从Java字节码的角度看线程安全性问题00:25:43分钟 | 第14节synchronized保证线程安全的原理(理论层面)00:13:59分钟 | 第15节synchronized保证线程安全的原理(jvm层面)00:25:03分钟 | 第16节单例问题与...

    深入JAVA虚拟机(第2版)

    3.4.3 第三趟:字节码验证 3.4.4 第四趟:符号引用的验证 3.4.5 二进制兼容 3.5 Java虚拟机中内置的安全特性 3.6 安全管理器和Java API 3.7 代码签名和认证 3.8 一个代码签名示例 3.9 策略 ...

    Java_Card虚拟机的研究与优化_杨富彪.caj

    在字节码解析方面,为了提升系统空间利用效率,通过对开发流程的分 析并结合虚拟机卡内和卡外协同合作的思想,在详细阐述传统动静态 解析过程的基础上设计了基于协同思想的动静态解析优化方案,减少了系统空间资源 ...

Global site tag (gtag.js) - Google Analytics