转载地址

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

  类文件{

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

  }

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

  例子:有一个Java类Demo.java

 public class Demo {
private String str1;
private String str2;
private int num1;
private int num2;
public static final String STATIC_DATA = "hello world"; private void sayHello1(){
System.out.println("this is method1...");
}
private void sayHello2(){
System.out.println("this is method2...");
}
public void sayHello3(){
System.out.println("this is method3...");
}
}

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

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

Demo.txt:

 Compiled from "Demo.java"
public class Demo extends java.lang.Object
SourceFile: "Demo.java"
minor version: 0
major version: 49 Constant pool:
const #1 = class #2; // Demo
const #2 = Asciz Demo;
const #3 = class #4; // java/lang/Object
const #4 = Asciz java/lang/Object;
const #5 = Asciz str1;
const #6 = Asciz Ljava/lang/String;;
const #7 = Asciz str2;
const #8 = Asciz num1;
const #9 = Asciz I;
const #10 = Asciz num2;
const #11 = Asciz STATIC_DATA;
const #12 = Asciz ConstantValue;
const #13 = String #14; // hello world
const #14 = Asciz hello world;
const #15 = Asciz <init>;
const #16 = Asciz ()V;
const #17 = Asciz Code;
const #18 = Method #3.#19; // java/lang/Object."<init>":()V
const #19 = NameAndType #15:#16;// "<init>":()V
const #20 = Asciz LineNumberTable;
const #21 = Asciz LocalVariableTable;
const #22 = Asciz this;
const #23 = Asciz LDemo;;
const #24 = Asciz sayHello1;
const #25 = Field #26.#28; // java/lang/System.out:Ljava/io/PrintStream;
const #26 = class #27; // java/lang/System
const #27 = Asciz java/lang/System;
const #28 = NameAndType #29:#30;// out:Ljava/io/PrintStream;
const #29 = Asciz out;
const #30 = Asciz Ljava/io/PrintStream;;
const #31 = String #32; // this is method1...
const #32 = Asciz this is method1...;
const #33 = Method #34.#36; // java/io/PrintStream.println:(Ljava/lang/String;)V
const #34 = class #35; // java/io/PrintStream
const #35 = Asciz java/io/PrintStream;
const #36 = NameAndType #37:#38;// println:(Ljava/lang/String;)V
const #37 = Asciz println;
const #38 = Asciz (Ljava/lang/String;)V;
const #39 = Asciz sayHello2;
const #40 = String #41; // this is method2...
const #41 = Asciz this is method2...;
const #42 = Asciz sayHello3;
const #43 = String #44; // this is method3...
const #44 = Asciz this is method3...;
const #45 = Asciz SourceFile;
const #46 = Asciz Demo.java; {
public static final java.lang.String STATIC_DATA;
Constant value: String hello world
public Demo();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #18; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 2: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LDemo; public void sayHello3();
Code:
Stack=2, Locals=1, Args_size=1
0: getstatic #25; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #43; //String this is method3...
5: invokevirtual #33; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 17: 0
line 18: 8
LocalVariableTable:
Start Length Slot Name Signature
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

 <strong>public class TestString {
public String testString(String str1, String str2){
return str1 + str2;
}
public String testStringBuffer(StringBuffer sb, String str){
return sb.append(str).toString();
}
}
</strong>

javap –c TestString 后字节码信息:

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

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

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

 
 

Java之字节码(1) - 深入解析的更多相关文章

  1. Java Class 字节码文件结构详解

    Class字节码中有两种数据类型: 字节数据直接量:这是基本的数据类型.共细分为u1.u2.u4.u8四种,分别代表连续的1个字节.2个字节.4个字节.8个字节组成的整体数据. 表:表是由多个基本数据 ...

  2. 【java虚拟机系列】从java虚拟机字节码执行引擎的执行过程来彻底理解java的多态性

    我们知道面向对象语言的三大特点之一就是多态性,而java作为一种面向对象的语言,自然也满足多态性,我们也知道java中的多态包括重载与重写,我们也知道在C++中动态多态是通过虚函数来实现的,而虚函数是 ...

  3. java虚拟机字节码执行引擎

    定义 java虚拟机字节码执行引擎是jvm最核心的组成部分之一,它做的事情很简单:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果.在不同的虚拟机实现里,执行引擎在执行java代码 ...

  4. 小师妹学JVM之:java的字节码byte code简介

    目录 简介 Byte Code的作用 查看Byte Code字节码 java Byte Code是怎么工作的 总结 简介 Byte Code也叫做字节码,是连接java源代码和JVM的桥梁,源代码编译 ...

  5. 聊聊Java的字节码

    本文为作者原创,转载请注明出处(http://www.cnblogs.com/mar-q/)by 负赑屃 巴山楚水凄凉地,二十三年弃置身.怀旧空吟闻笛赋,到乡翻似烂柯人.沉舟侧畔千帆过,病树前头万木春 ...

  6. java class 字节码

    java class 字节码 协议: class文件 魔数(Magic):4byte -> 0xCAFEBABE 类似2f3f 版本(Version):4Byte -> 0x0000003 ...

  7. 使用java动态字节码技术简单实现arthas的trace功能。

    参考资料 ASM 系列详细教程 编译时,找不到asm依赖 用过[Arthas]的都知道,Arthas是alibaba开源的一个非常强大的Java诊断工具. 不管是线上还是线下,我们都可以用Arthas ...

  8. 从字节码层面,解析 Java 布尔型的实现原理

    最近在系统回顾学习 Java 虚拟机方面的知识,其中想到一个很有意思的问题:布尔型在虚拟机中到底是什么类型? 要想解答这个问题,我们看 JDK 的源码是无法解决源码的,我们必须深入到 class 文件 ...

  9. Java 动态字节码技术

    对 Debug 的好奇 初学 Java 时,我对 IDEA 的 Debug 非常好奇,不止是它能查看断点的上下文环境,更神奇的是我可以在断点处使用它的 Evaluate 功能直接执行某些命令,进行一些 ...

随机推荐

  1. Varnish与Squid的对比

    Varnish与Squid的对比 说到Varnish,就不能不提Squid.Squid是一个高性能的代理缓存服务器,它和Varnish相比较有诸多的异同点,下面进行分析. 下面是Varnish与Squ ...

  2. poj 2912 并查集(食物链加强版)

    题目:给出n个人玩剪刀石头布的游戏,其中有一个人是裁判,剩下的人分为3组,每一组的人只出某一种手型,裁判可以任意出.问是否能判断出哪个人是裁判 链接:点我 分分钟看吐血,先把食物链看懂吧 枚举裁判,然 ...

  3. VK Cup 2016 - Qualification Round 2 D. Three-dimensional Turtle Super Computer 暴力

    D. Three-dimensional Turtle Super Computer 题目连接: http://www.codeforces.com/contest/638/problem/D Des ...

  4. StringFormat

    public class StringFormatDemo { public static void main(String[] args) { String str = null; str = St ...

  5. <摘录>linux文件IO

    这篇文章写的比较全面,也浅显易懂,备份下.转载自:http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的 ...

  6. layer弹框,弹出后自动关闭

    今天做项目,出现一个问题,需求是用ajax做文件上传功能,代码写好之后,测试发现问题. 弹出层出现以后我没有主动点击确定和关闭等操作,程序自动关闭了弹出层 一步一步排查,找到了错误,首先,先确认你页面 ...

  7. IOS上传图片方法类

    IOS上传图片方法类   iPhone开发中遇到上传图片问题,找到多资料,最终封装了一个类,请大家指点,代码如下 // // RequestPostUploadHelper.h // demodes ...

  8. HDU 4675 GCD of Sequence (2013多校7 1010题 数学题)

    GCD of Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

  9. 分享我用Taker做任务时需要的各种资源的精华帖,方便查阅

    http://tieba.baidu.com/p/2310764470 第一名 [Tasker论坛] https://groups.google.com/group/tasker/?pli=1http ...

  10. 实战DELPHI:远程线程插入(DLL注入)

    http://www.jx19.com/xxzl/Delphi/2010/04/17/ShiZhanDELPHI_YuanChengXianChengChaRu_DLLZhuRu/ 远程注入DLL方法 ...