举个例子:

 public class ExceptionTest{

     void cantBeZero(int i) throws Exception{
throw new Exception(); } }

上面代码编译后的字节码指令如下:

  void cantBeZero(int) throws java.lang.Exception;
descriptor: (I)V
flags:
Code:
stack=2, locals=2, args_size=2
0: iload_1
1: ifne 12
4: new #2 // class java/lang/Exception
7: dup
8: invokespecial #3 // Method java/lang/Exception."<init>":()V
11: athrow
12: return

1) 其中new指令在java堆上为Exception对象分配内存空间,并将地址压入操作数栈顶;

2) 然后dup指令为复制操作数栈顶值,并将其压入栈顶,也就是说此时操作数栈上有连续相同的两个对象地址;

3) invokespecial指令调用实例初始化方法<init>:()V,注意这个方法是一个实例方法,所以需要从操作数栈顶弹出一个this引用,也就是说这一步会弹出一个之前入栈的对象地址;

4) athrow指令从操作数栈顶取出一个引用类型的值,并抛出;

5) 最后由return指令结束方法。

从上面的五个步骤中可以看出,需要从栈顶弹出两个实例对象的引用,这就是为什么会在new指令下面有一个dup指令,其实对于每一个new指令来说一般编译器都会在其下面生成

一个dup指令,这是因为实例的初始化方法肯定需要用到一次,然后第二个留给程序员使用,例如给变量赋值,抛出异常等,如果我们不用,那编译器也会生成dup指令,在初始化方法调用完成后再从栈顶pop出来。例如我们仅仅创建一个对象而不做任何操作,例如:

     void cantBeZero(int i) throws Exception{
new Exception(); }

上面的代码仅仅创建了一个Exception对象,而没有做任何操作。

其编译后的字节码指令如下:

  void cantBeZero(int) throws java.lang.Exception;
descriptor: (I)V
flags:
Code:
stack=2, locals=2, args_size=2
0: new #2 // class java/lang/Exception
3: dup
4: invokespecial #3 // Method java/lang/Exception."<init>":()V
7: pop
8: return

也会生成一个dup指令,只不过在调用完实例初始化方法后,将重复的实例引用又pop出栈了。不过这种情况基本不会出现在我们的代码中,因为我们创建的每一个对象都应该是有用的。

通过上面的例子你应该比较清楚的理解了为什么创建对象时总会有一个dup指令了。

java虚拟机指令dup的理解的更多相关文章

  1. java 虚拟机指令重新排序

    指令重排序是JVM为了优化指令,提高程序运行效率,在不影响单线程程序执行结果的前提下,尽可能地提高并行度.编译器.处理器也遵循这样一个目标.注意是单线程.多线程的情况下指令重排序就会给程序员带来问题. ...

  2. 深入理解java虚拟机(六)字节码指令简介

    Java虚拟机指令是由(占用一个字节长度.代表某种特定操作含义的数字)操作码Opcode,以及跟随在其后的零至多个代表此操作所需参数的称为操作数 Operands 构成的.由于Java虚拟机是面向操作 ...

  3. [三] java虚拟机 JVM字节码 指令集 bytecode 操作码 指令分类用法 助记符

    说明,本文的目的在于从宏观逻辑上介绍清楚绝大多数的字节码指令的含义以及分类 只要认真阅读本文必然能够对字节码指令集有所了解 如果需要了解清楚每一个指令的具体详尽用法,请参阅虚拟机规范 指令简介 计算机 ...

  4. (1) 深入理解Java虚拟机到底是什么?

    好文转载:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机   作为一个Java程序员,我们每天都在写Java ...

  5. 深入理解Java虚拟机到底是什么

    摘自:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机 我们都知道Java程序必须在虚拟机上运行.那么虚拟机到 ...

  6. 《深入理解Java虚拟机》-----第6章 类文件结构——Java高级开发必须懂的

    代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 6.1 概述 记得在第一节计算机程序课上我的老师就讲过:“计算机只认识0和1,所以我们写的程序需要经编译器翻 ...

  7. 《深入理解java虚拟机》第六章 类文件结构

    第六章 类文件结构   6.2 无关性的基石 各种不同平台的虚拟机与所有的平台都统一使用的程序存储格式--字节码(ByteCode)是构成平台无关性的基石.java虚拟机不和包括java在内的任何语言 ...

  8. Atitit.java 虚拟机的构成 与指令分类 与 指令集合 以及字节码查看工具javjap

    Atitit.java 虚拟机的构成 与指令分类 与 指令集合 以及字节码查看工具javjap 1.1. 虚拟机的构成 java虚拟机--处理器.堆栈.寄存器.指令系统. 1 1.2. 虚拟机执行过程 ...

  9. 深入理解Java虚拟机到底是什么(转)

    原文链接:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机   作为一个Java程序员,我们每天都在写Java ...

随机推荐

  1. Spring security csrf实现前端纯html+ajax

    spring security集成csrf进行post等请求时,为了防止csrf攻击,需要获取token才能访问 因此需要添加 <input type="hidden" na ...

  2. Python-老男孩-02_装饰器_面向对象_封装_继承_异常_接口_数据库

    装饰器其实也是一个函数,它的参数是一个函数 ; 其它函数与装饰器之间建立联系是通过 @装饰器函数名, 感觉有点像Spring的面向切面编程 装饰器函数,如何处理原函数的参数.?  装饰器 原函数返回值 ...

  3. Ubuntu Server 12.04安装图解教程

                                                                                                Ubuntu S ...

  4. Java http请求和调用

    关于http get和post请求调用代码以及示例. 参考:http://www.cnblogs.com/zhuawang/archive/2012/12/08/2809380.html http请求 ...

  5. Java为什么把String设计成不可变的(immutable)

    在java中,String是字符串常量,可以从内存,同步机制,数据结构等方面分析 1:字符串中常量池的需要 String不同于普通基础变量类型的地方在于对象.java中的字符串对象都保存在字符串常量池 ...

  6. IIC-BUS INTERFACE

    I2C总线是由Philips公司开发的一种简单.双向二线制同步串行总线.它只需要两根线即可在连接于总线上的器件之间传送信息. To control multi-master IIC-bus opera ...

  7. 协议端口号(protocol port number)

    协议端口号(protocol port number) 先来个注意事项 (-> ->) 这种在协议层间的抽象的协议端口是软件端口,和硬件端口是完全不同的概念.硬件端口是不同设备进行交互的接 ...

  8. 为ASP.NetCore程序启用SSL

    紧接着上一篇搭建连接MySql的三层架构的ASP.NetCore2.0的WebApi的案例,这篇来实现为ASP.NetCore启用SSL支持 由于ASP.NetCore默认服务器Kestrel不像ii ...

  9. Python NLP入门教程

    本文简要介绍Python自然语言处理(NLP),使用Python的NLTK库.NLTK是Python的自然语言处理工具包,在NLP领域中,最常使用的一个Python库. 什么是NLP? 简单来说,自然 ...

  10. SSM之整合Redis

    Redis安装与使用 第一步当然是安装Redis,这里以Windows上的安装为例. 首先下载Redis,可以选择msi或zip包安装方式 zip方式需打开cmd窗口,在解压后的目录下运行redis- ...