引言:

之前一篇文章梳理了String的不变性原则,还提到了一段源码中注释"avoid getfield opcode",当时通过查阅资料发现,这是为了防止 getfield(获取指定类的实例域,并将其值压入到栈顶)这个操作码的执行,这篇文章想从字节码的角度去分析一下。


先看一段代码吧

/**
* Created by chenqimiao on 16/11/29.
*/
public class Main { public char[] chars = new char[10]; public void test() {
System.out.println(chars[0]);
System.out.println(chars[1]);
System.out.println(chars[2]);
} public static void main(String args[]) {
Main m = new Main();
m.test();
}
}

  执行 javap -c Main ,分析一下字节码,查看一下分析后生成的操作码:

查阅"深入理解JVM虚拟机"一书中的虚拟机字节码指令表,试着分析一下test方法下面的code.

4.获取指定的实例域,并将其值压入栈顶

7.将int型0推送至栈顶

8.将char数组指定索引的值推至栈顶

9.调用实例方法

总结一下的话,就是每次获取实例域 推到栈顶,然后推被操作的索引到栈顶,然后取到对应数组的指定索引的值推到栈顶,然后就是调用输出方法了。可以看到输出三次,getfield操作码就调用了三次,假想我们在遍历这个char数组,那象上述写法,要频繁调用getfield操作码了。

我们学一下String源码中的写法,可能能改善一下这个问题。

/**
* Created by chenqimiao on 16/11/29.
*/
public class Main { public char[] chars = new char[10]; public void test() {
char[] chars = this.chars;
System.out.println(chars[0]);
System.out.println(chars[1]);
System.out.println(chars[2]);
} public static void main(String args[]) {
Main m = new Main();
m.test();
}
}

  

  执行 javap -c Main ,分析一下字节码,查看一下分析后生成的操作码:

好了,我把实例变量的数组的引用赋给了一个局部引用了。

我们还是分析一下test方法中的code把

0.将第一个引用类型本地变量推送至栈顶(就是将局部变量引用chars放到栈顶)

1.获取实例域的引用推到栈顶(实例变量的成员chars放到栈顶)

4.将栈顶顶引用类型数值存入指定本地变量(就是把成员变量chars的引用给到局部变量的引用chars,这里是引用值拷贝,不是引用指向内存的值的拷贝)

5.获取指定的实例域,并将其值压入栈顶

8.将第二个引用类型本地变量推送至栈顶

9.将int型0推到栈顶

10.将char数组指定的索引的值压入到栈顶

11.调用实例方法(输出)

在14-20的过程中没有再发生"getfield"操作,而是用aload_1操作码将第二个本地引用(被赋值后的本地引用chars)推至栈顶,就可以执行接下来的一系列操作。

到这里的话"avoid getfield opcode"的意思已经非常清楚明了,在遍历实例的char数组的时候,将实例数组的引用赋值给一个本地引用,不需要频繁调用操作用码"getfield",只需要在第一次对本地引用赋值的时候,调用一次getfield,接下来的遍历取值的时候,只需要将本地引用压入到栈顶。

 

 

String源码中的"avoid getfield opcode"的更多相关文章

  1. String源码中hashCode算法

    针对java中String源码hashcode算法源码分析 /** The value is used for character storage. */ private final char val ...

  2. java面试之String源码中equals具体实现

    废话不多说,直接看代码,注释已经写在上面了: public boolean equals(Object anObject) { if (this == anObject) {//比较两个对象的地址 r ...

  3. 程序兵法:Java String 源码的排序算法(一)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 <程序兵法:Java Str ...

  4. JDK代码中的优化 之 “avoid getfield opcode”

    在查看String类源码时,常看到注释 /* avoid getfield opcode */ 如 trim()方法 public String trim() { int len = value.le ...

  5. (转)Java中的String为什么是不可变的? -- String源码分析

    背景:被问到很基础的知识点  string  自己答的很模糊 Java中的String为什么是不可变的? -- String源码分析 ps:最好去阅读原文 Java中的String为什么是不可变的 什 ...

  6. java基础进阶一:String源码和String常量池

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8046564.html 邮箱:moyi@moyib ...

  7. 基于JDK1.8的String源码学习笔记

    String,可能是学习Java一上来就学习的,经常用,但是却往往只是一知半解,甚至API有时也得现查.所以还是老规矩,倒腾源码. 一.java doc 这次首先关注String的doc,因为其实作为 ...

  8. Java基础(八)--String(源码)、StringBuffer、StringBuilder

    String源码:基于jdk1.8 public final class String implements Serializable, Comparable<String>, CharS ...

  9. 死啃了String源码之后

    Java源码之String 说在前面: 为什么看源码: 最好的学习的方式就是模仿,接下来才是创造.而源码就是我们最好的模仿对象,因为写源码的人都不是一般的人,所以用心学习源码,也就可能变成牛逼的人.其 ...

随机推荐

  1. gem安装报错解决方法

    gem install  rdiscount -- --use-system-libraries

  2. 生成Json文件

  3. 【优雅代码】深入浅出 妙用Javascript中apply、call、bind

    这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: “对我来说,博客首先是一种知识管理工具,其次才是传播工具.我的技术文章,主要用来整理我还不懂的知识.我 ...

  4. Excel单元格发生变化后,使用Outlook给特定的人发邮件

    自己在公司里面维护了一个小金库的Excel,当某个人的余额小于0的时候,Outlook会自动给这个人发一封邮件,同时将这个Excel附在邮件中,具体的代码如下: Public Function sen ...

  5. Dash文档制作教程

    前言 什么是Dash 面向程序员的文档库(Mac) 代码片段管理工具 这是强烈推荐给每天在各种API文档中摸爬滚打的程序员们的神器. 为什么要自己制作文档 官方的源中没有相关文档 文档在离线下体验更好 ...

  6. CentOS RDO方式快速安装OpenStack

    一.了解RDO RDO是什么? RDO是红帽Red Hat Enterprise Linux OpenStack Platform的社区版,类似RHEL和Fedora,RHEV和oVirt这样的关系. ...

  7. js实用篇之String对象

    概述 String对象是JavaScript原生提供的三个包装对象之一,用来生成字符串的包装对象. var s1 = 'abc'; var s2 = new String('abc'); typeof ...

  8. WebDriver--简单的元素操作

    以登录163邮箱为例,演示以下几个方法的使用 ①switch_to.frame() ②.clear() ③.send_keys() ④.click() ⑤switch_to_default_conte ...

  9. HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application

    j 今天下午一直报这个问题,google了半天没有找到答案.百度了下,说是 tomcat的 lib文件夹下缺少jstl1.2,因为项目里面用的也是 jstl1.2和 standard-1.1.2.ja ...

  10. Android笔记——eclipse快捷键

    查看快捷键定义的地方 Window->Preferences->General->Keys. 编辑相关快捷键 1. [ALT+/] 自动提示方法 此快捷键为用户编辑的好帮手,能为用户 ...