使用 javap 深入查看类文件 _maoerzuozuo的博客-程序员宅基地

技术标签: Java  汇编  java  编译器  string  开发工具  class  

Java 开发人员熟悉在一个循环中使用StringBuffer 来代替串联 String 对象能获得最佳性能。然而,多数开发人员从来没有比较两种方法产生的字节代码的区别。在 Java 开发工具包(JDK)中有一个叫做 javap 的工具可以告诉你为什么这样做可以获得最佳性能。

<script language=JavaScript1.1 src="http://ad.cn.doubleclick.net/adj/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=1040633726?"> </script> <script language=VBScript> on error resume next ShockMode = (IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash.6"))) </script>

Javap 将一个类和它的方法的一些转储信息输出到标准输出。该工具不把代码反编译为 java 源代码,但是它会把字节代码反汇编成为由 Java 虚拟机规范定义的字节代码指令。

在你需要查看编译器为你或者给你做了什么的时候,或者你想要看一处代码的改动对编译后的类文件有什么影响的时候,javap 相当有用。

现在以我们前面提到的 StringBuffer 和 String 作为一个例子。下面是一个专门为例子设计的类,它有两个方法,都返回一个由0到 n 的数字组成的 String,其中 n 由调用者提供。两个方法唯一的区别在于一个使用 String 构建结果,另外一个使用 StringBuffer 构建结果。

public class JavapTip {
    public static void main(String []args) {
    }

    private static String withStrings(int count) {
        String s = "";
        for (int i = 0; i < count; i++) {
            s += i;
        }

        return s;
    }

    private static String withStringBuffer(int count) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < count; i++) {
            sb.append(i);
        }

        return sb.toString();
    }
}

现在让我们看看对这个类使用–c 选项运行 javap 的输出。-c 选项告诉 javap 反汇编在类中遇到的字节代码。

运行方式如下:

>javap -c JavapTip

此命令的输出为:

Method java.lang.String withStrings(int)
   0 ldc #2 <String "">
   2 astore_1
   3 iconst_0
   4 istore_2
   5 goto 30
   8 new #3 <Class java.lang.StringBuffer>
  11 dup
  12 invokespecial #4 <Method java.lang.StringBuffer()>
  15 aload_1
  16 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  19 iload_2
  20 invokevirtual #6 <Method java.lang.StringBuffer append(int)>
  23 invokevirtual #7 <Method java.lang.String toString()>
  26 astore_1
  27 iinc 2 1
  30 iload_2
  31 iload_0
  32 if_icmplt 8
  35 aload_1
  36 areturn

Method java.lang.String withStringBuffer(int)
   0 new #3 <Class java.lang.StringBuffer>
   3 dup
   4 invokespecial #4 <Method java.lang.StringBuffer()>
   7 astore_1
   8 iconst_0
   9 istore_2
  10 goto 22
  13 aload_1
  14 iload_2
  15 invokevirtual #6 <Method java.lang.StringBuffer append(int)>
  18 pop
  19 iinc 2 1
  22 iload_2
  23 iload_0
  24 if_icmplt 13
  27 aload_1
  28 invokevirtual #7 <Method java.lang.String toString()>
  31 areturn

如果你以前没有看过 Java 汇编器,那么这个输出对你来说就会比较难懂,但是你应该可以看到 withString 方法在每次循环的时候都新创建了一个 StringBuffer 实例。然后它将已有的 String 的当前值追加到 StringBuffer 上,然后追加循环的当前值。最后,它对 buffer 调用 toString 并将结果赋给现有的 String 引用。

withStringBuffer 方法与这个方法正好相反,在每次循环的时候 withStringBuffer 只调用现有 StringBuffer 的 append 方法,没有创建新的对象,也没有新的 String 引用。

在这种情况下,我们已经知道了使用 StringBuffer 代替 String 是一种好的做法,但是如果我们不知道呢?那么 javap 可以帮助我们找到答案。

你并不会经常需要一个 Java 反汇编器,但是当你需要的时候,知道你自己的机器已经有一个并且用法相当简单的反汇编器当然是一件好事。如果你感兴趣,看书看看 javap 的其它选项——或许你会发现在你的环境中需要的特性。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/maoerzuozuo/article/details/92625

智能推荐

实战案例:python 基于opencv 绘制图像轮廓的示例_49.99%的博客-程序员宅基地_python图像轮廓

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理本文章来自腾讯云 作者:Python知识大全想要学习Python?有问题得不到第一时间解决?来看看这里“1039649593”满足你的需求,资料都已经上传至文件中,可以自行下载!还有海量最新2020python学习资料。点击查看这篇文章主要介绍了python 基于opencv 绘制图像轮廓的示例,帮助大家更好的利用python的opencv库处理图像,感兴趣的朋友可以了解下图像

两个列表(list)组成字典(dict)_James_Bobo的博客-程序员宅基地_两个list组成字典

# -*- coding: utf-8 -*-keys = ['a', 'b', 'c']values = [1, 2, 3]dictionary = dict(zip(keys, values))print dictionary"""输出:{'a': 1, 'c': 3, 'b': 2}"""

springmvc出现500错误_爱吃葱的小石头的博客-程序员宅基地_springmvc报500

原来忘了添加了classpath的指定文件,添加后就可以了

圣诞表白html,适合圣诞节表白的文案句子 圣诞节表白文案合集大全_把夏天绑在鞋带上的博客-程序员宅基地

圣诞节是这个冬天里很浪漫的一个节日,也是非常适合表白的,在浪漫的氛围里,说着暖心的表白情话,会让感情迅速升温,下面八宝网小编就带来适合圣诞节表白的文案句子,圣诞节表白文案合集大全。适合圣诞节表白的文案句子1、今年圣诞老人也很忙哦,所以轮到我给圣诞惊喜给你咯。2、我一直以为我期待的是圣诞老人,没想到我心里想的是你。3、我跟圣诞老人说,礼物是我,小朋友,是你。4、如果明天,一个胖老头,爬进你的窗户,抓...

安卓so文件转linux,android linux編譯tensorflow的jar包和so文件_我是一只大猩猩的博客-程序员宅基地

本來想在win10上編譯的,結果失敗了就搞了個虛擬機系統:ubuntu 17.04先安裝java 的jdk去官網下載linux的jdk解壓到當前文件夾$ tar -zxvf xxxx.tar.gz打開profile文件$sudo gedit /etc/profile設置環境變量JAVA_HOME=/xxx/jdk //xxx表示路徑JRE_HOME=$JAVA_HOME/jreCLASS...

路飞项目-数据结构设计_weixin_30390075的博客-程序员宅基地

后端发送数据结构设计数据结构后端发送数据结构"""code:状态码,判断数据状态error:错误信息,数据校验失败,后端主动发送的错误信息data:数据校验成功后,发送的有用信息"""{ code:1001 error:'' data:''}代码  class BaseResponse(object): ...

随便推点

ajax append一个html,php jquery ajax append(html) in a loop_赖振波的博客-程序员宅基地

Function;jQuery(function($){function detail(dataone) {$.ajax({url: "detail.php?name=" + dataone,cache: false}).done(function( html ) {$("#detail").append(html);}).fail(function(jqXHR, ajaxOptions, thr...

springboot获取多个请求参数_springboot获取URL请求参数的多种方式_赵泠的博客-程序员宅基地

1、直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交。/*** 1.直接把表单的参数写在Controller相应的方法的形参中*@paramusername*@parampassword*@return*/@RequestMapping("/addUser1")publicString addUser1(String username,St...

热门网络开源框架和图片开源框架的使用方法_tianzhu2725的博客-程序员宅基地

学习目标熟练掌握目前最流行网络请求类库的使用,如:Ion:Android Asynchronous Networking and Image LoadingVolley:谷歌官方推出的网络请求和图片加载库Retrofit:Square开源的基于OKHttp的性能良好更安全的类库熟练掌握目前最流行图片加载类库的使用,如:Glide:专注于处理流畅加载的图片类库Picass

深度学习这么调参训练_深度学习训练的小技巧,调参经验(转)_weixin_39726044的博客-程序员宅基地

经常会被问到你用深度学习训练模型时怎么样改善你的结果呢?然后每次都懵逼了,一是自己懂的不多,二是实验的不多,三是记性不行忘记了。所以写这篇博客,记录下别人以及自己的一些经验。Ilya Sutskever(Hinton的学生)讲述了有关深度学习的见解及实用建议:获取数据:确保要有高质量的输入/输出数据集,这个数据集要足够大、具有代表性以及拥有相对清楚的标签。缺乏数据集是很难成功的。预处理:将数据进行...

oracle怎么查询序列的cache,Oracle 11g 新特性 -- Result Cache(结果高速缓存)说明_weixin_39570777的博客-程序员宅基地

一.Result Set Caching 说明Oracle 官网的说明,参考:7.6 Managing the Server and ClientResult Caches1.1 概述SQL 查询结果高速缓存可在数据库内存中对查询结果集和查询碎片启用显式高速缓存。存储在共享池(Share Pool)中的专用内存缓冲区可用于存储和检索高速缓存的结果。对查询访问的数据库对象中的数据进行修改后,存储在该...

五种创建UIImage的类方法_lceBear的博客-程序员宅基地

iOS开发已开通评论功能皇天不负有心人,iOS开发的评论功能已经被邀请开通啦。这几天一直想着。微信团队大概在月底的时候会邀请我开通评论功能。果然不出我所料。这是我收到的消息:至此,iOS开发的原创、观赏、评论三个功能都齐啦,这也是对我辛苦努力的一种肯定。前方的路依旧非常漫长,我们一起努力。让iOS开发变得更好。既然评论功能已经开通,大家也别闲着啦!今天...

推荐文章

热门文章

相关标签