`
329937021
  • 浏览: 122607 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java字节码学习之MethodInvoke

阅读更多
学习Java字节码有助于理解Java内存结构,加深对JVM的理解。



    首先需要知道JVM内存由堆、栈、方法区、本地方法栈组成。
    堆中存放JVM生命周期里所有的类的实例。
    栈中存放函数中的基础类型局部变量、函数中实例变量的引用。
    方法区存放Class、Method的信息以及Static的变量。
    本地方法栈存放调用本地方法时用到的变量。

    JVM为每个线程都分配了一个方法栈,方法栈包含不同方法的栈帧,每个方法都有一个栈帧,当前方法的栈帧称为当前栈帧,栈帧由局部变量区和操作数栈组成,所有线程共享堆中的数据。

    下面以一个简单的Java程序HelloWorld.java为例,介绍一下Java方法调用时的内存结构。

源代码
Java代码
public class HelloWorld {   
    private String myWorld;   
  
    public HelloWorld(String world) {   
        this.myWorld = world;   
    }   
  
    public String getMyWorld() {   
        return myWorld;   
    }   
  
    public void setMyWorld(String myWorld) {   
        this.myWorld = myWorld;   
    }   
       
    public boolean isNull(){   
        if(this.myWorld==null){   
            return true;   
        }else{   
            return false;   
        }   
    }   
       
    public static void main(String[]args){   
        HelloWorld myWorld = new HelloWorld("smallWorld");   
        boolean isNull = false;   
        myWorld.setMyWorld("bigWorld");   
        isNull = myWorld.isNull();   
    }   
}  

public class HelloWorld {
	private String myWorld;

	public HelloWorld(String world) {
		this.myWorld = world;
	}

	public String getMyWorld() {
		return myWorld;
	}

	public void setMyWorld(String myWorld) {
		this.myWorld = myWorld;
	}
	
	public boolean isNull(){
		if(this.myWorld==null){
			return true;
		}else{
			return false;
		}
	}
	
	public static void main(String[]args){
		HelloWorld myWorld = new HelloWorld("smallWorld");
		boolean isNull = false;
		myWorld.setMyWorld("bigWorld");
		isNull = myWorld.isNull();
	}
}


Javap -C HelloWorld

字节码:
Java代码
Compiled from "HelloWorld.java"  
public class com.sitech.core.HelloWorld extends java.lang.Object{   
public com.sitech.core.HelloWorld(java.lang.String);   
  Code:   
   0:   aload_0   
   1:   invokespecial   #10; //Method java/lang/Object."<init>":()V   
   4:   aload_0   
   5:   aload_1   
   6:   putfield        #13; //Field myWorld:Ljava/lang/String;   
   9:   return  
  
public java.lang.String getMyWorld();   
  Code:   
   0:   aload_0   
   1:   getfield        #13; //Field myWorld:Ljava/lang/String;   
   4:   areturn   
  
public void setMyWorld(java.lang.String);   
  Code:   
   0:   aload_0   
   1:   aload_1   
   2:   putfield        #13; //Field myWorld:Ljava/lang/String;   
   5:   return  
  
public boolean isNull();   
  Code:   
   0:   aload_0   
   1:   getfield        #13; //Field myWorld:Ljava/lang/String;   
   4:   ifnonnull       9  
   7:   iconst_1   
   8:   ireturn   
   9:   iconst_0   
   10:  ireturn   
  
public static void main(java.lang.String[]);   
  Code:   
   0:   new     #1; //class HelloWorld   
   3:   dup   
   4:   ldc     #27; //String smallWorld   
   6:   invokespecial   #29; //Method "<init>":(Ljava/lang/String;)V   
   9:   astore_1   
   10:  iconst_0   
   11:  istore_2   
   12:  aload_1   
   13:  ldc     #31; //String bigWorld   
   15:  invokevirtual   #33; //Method setMyWorld:(Ljava/lang/String;)V   
   18:  aload_1   
   19:  invokevirtual   #35; //Method isNull:()Z   
   22:  istore_2   
   23:  return  
  
}  

Compiled from "HelloWorld.java"
public class com.sitech.core.HelloWorld extends java.lang.Object{
public com.sitech.core.HelloWorld(java.lang.String);
  Code:
   0:   aload_0
   1:   invokespecial   #10; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   aload_1
   6:   putfield        #13; //Field myWorld:Ljava/lang/String;
   9:   return

public java.lang.String getMyWorld();
  Code:
   0:   aload_0
   1:   getfield        #13; //Field myWorld:Ljava/lang/String;
   4:   areturn

public void setMyWorld(java.lang.String);
  Code:
   0:   aload_0
   1:   aload_1
   2:   putfield        #13; //Field myWorld:Ljava/lang/String;
   5:   return

public boolean isNull();
  Code:
   0:   aload_0
   1:   getfield        #13; //Field myWorld:Ljava/lang/String;
   4:   ifnonnull       9
   7:   iconst_1
   8:   ireturn
   9:   iconst_0
   10:  ireturn

public static void main(java.lang.String[]);
  Code:
   0:   new     #1; //class HelloWorld
   3:   dup
   4:   ldc     #27; //String smallWorld
   6:   invokespecial   #29; //Method "<init>":(Ljava/lang/String;)V
   9:   astore_1
   10:  iconst_0
   11:  istore_2
   12:  aload_1
   13:  ldc     #31; //String bigWorld
   15:  invokevirtual   #33; //Method setMyWorld:(Ljava/lang/String;)V
   18:  aload_1
   19:  invokevirtual   #35; //Method isNull:()Z
   22:  istore_2
   23:  return

}


重点看一下main方法中调用isNull方法的操作:

Java代码
public static void main(java.lang.String[]);   
  Code:   
   0:   new           //在堆中分配内存,返回对象引用,压入操作数栈   
   3:   dup           //复制引用,压入栈   
   4:   ldc           //将常量池中的常量smallWorld压入栈   
                         //JVM会将main方法操作数栈中的变量弹出放入构造函数的    
                         //局部变量区   
   6:   invokespecial //调用构造函数,弹出对象引用和参数   
                         //调用结束后,JVM会将构造函数返回值压入main方法操作数栈   
   9:   astore_1      //将对象引用弹出,存储在main方法局部变量1的位置   
   10:  iconst_0      //将false值压栈   
   11:  istore_2      //弹出false并存储于main方法局部变量2的位置   
   12:  aload_1       //将对象引用压栈   
   13:  ldc           //将将常量池中的常量bigWorld压入栈   
                         //JVM会将main方法操作数栈中的变量弹出放入实例方法   
                         //的局部变量区   
   15:  invokevirtual //调用实例函数setMyWorld,弹出对象引用和参数   
   18:  aload_1       //将对象引用存储在main方法局部变量1的位置   
                         //JVM会将main方法操作数栈中的变量弹出放入实例方法的   
                         //局部变量区   
   19:  invokevirtual //调用实例函数isNull,弹出对象引用和参数   
                         //调用结束后,JVM会将构造函数返回值压入main方法操作数栈   
   22:  istore_2      //弹出true并存储于main方法局部变量2的位置   
   23:  return  

public static void main(java.lang.String[]);
  Code:
   0:   new           //在堆中分配内存,返回对象引用,压入操作数栈
   3:   dup           //复制引用,压入栈
   4:   ldc           //将常量池中的常量smallWorld压入栈
                         //JVM会将main方法操作数栈中的变量弹出放入构造函数的 
                         //局部变量区
   6:   invokespecial //调用构造函数,弹出对象引用和参数
                         //调用结束后,JVM会将构造函数返回值压入main方法操作数栈
   9:   astore_1      //将对象引用弹出,存储在main方法局部变量1的位置
   10:  iconst_0      //将false值压栈
   11:  istore_2      //弹出false并存储于main方法局部变量2的位置
   12:  aload_1       //将对象引用压栈
   13:  ldc           //将将常量池中的常量bigWorld压入栈
                         //JVM会将main方法操作数栈中的变量弹出放入实例方法
                         //的局部变量区
   15:  invokevirtual //调用实例函数setMyWorld,弹出对象引用和参数
   18:  aload_1       //将对象引用存储在main方法局部变量1的位置
                         //JVM会将main方法操作数栈中的变量弹出放入实例方法的
                         //局部变量区
   19:  invokevirtual //调用实例函数isNull,弹出对象引用和参数
                         //调用结束后,JVM会将构造函数返回值压入main方法操作数栈
   22:  istore_2      //弹出true并存储于main方法局部变量2的位置
   23:  return


再来看看isNull方法:

Java代码
public boolean isNull();   
  Code:   
   0:   aload_0         //将局部变量区的对象引用参数压栈   
   1:   getfield        //访问堆区的类实例   
   4:   ifnonnull       //是否为空   
   7:   iconst_1        //如果是true,将1压入操作数栈   
   8:   ireturn   
   9:   iconst_0        //如果是false,将0压入操作数栈   
   10:  ireturn  

public boolean isNull();
  Code:
   0:   aload_0         //将局部变量区的对象引用参数压栈
   1:   getfield        //访问堆区的类实例
   4:   ifnonnull       //是否为空
   7:   iconst_1        //如果是true,将1压入操作数栈
   8:   ireturn
   9:   iconst_0        //如果是false,将0压入操作数栈
   10:  ireturn


方法调用结束后,JVM会将isNull操作数栈中的返回值压入main方法的操作数栈中。
分享到:
评论

相关推荐

    java反射机制及Method.invoke解释

    java反射机制描述及Method.invoke解释

    Java反射机制及Method.invoke详解

    主要介绍了Java反射机制及Method.invoke详解,本文讲解了JAVA反射机制、得到某个对象的属性、得到某个类的静态属性、执行某对象的方法、执行某个类的静态方法等内容,需要的朋友可以参考下

    java反射机制详解及Method.invoke解释.pdf

    java反射机制详解及Method.invoke解释.pdf

    详解Java中Method的Invoke方法

    主要介绍了详解Java中Method的Invoke方法,需要的朋友可以参考下

    Java Method类及invoke方法原理解析

    主要介绍了Java Method类及invoke方法原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java开发技术大全(500个源代码).

    invokeStaticMethod.java 调用静态方法示例 localVariable.java 演示局部变量 localVSmember.java 局部变量与成员变量同名问题示例 onlyTest.java 对象传值示例 otherClass.java 从类的外部访问对象的成员 ...

    fabric-sdk-java+ springBoot 简单invoke和query引用示例

    这是一个基于spingBoot的项目,通过此项目可以实现对fabric...5,执行QueryChaincode.java,或是InvokeChaincode.java 6,启动web服务:执行DemoApplication.java 详细教程见: https://mp.csdn.net/postedit/88354838

    java反射简单例子demo

    java reflect Method getDeclaredMethod invoke getConstructor

    How to invoke Java web service in ASP

    How to invoke Java web service in ASP

    fabric-sdk-java+springBoot invoke和query引用示例

    详细教程请打开https://blog.csdn.net/qq_27348837/article/details/88354838 这是一个基于spingBoot的项目,通过此项目可以实现对fabric网络的简单调用,并且可以启动一个fabric网路的服务,直接在网页上调用.

    深入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...

    关于c#委托及委托异步的经典诠释

    这个文章是某位高人所写,委托及其异步运用写得很精辟(老有转c#的同学问这个,其实他们不知道这玩意跟指针没多大区别,只是微软把他封了一层又一层而已,看明白了用就行了).不过这个异步是上古写法了,现在都用async~...

    深入java虚拟机(inside the java virtual machine)

    Invoking a Java Method Invoking a Native Method Other Forms of Method Invocation The invokespecial instruction invokespecial and () invokespecial and Private Methods invokespecial and super The...

    Invoke反射

    本程序实现Invoke反射,内置说明txt文档,可以参考

    java head space.txt

    以下的问题是由于java的堆内存已满,需要java运行时加大java的堆内存空间 2019-10-09 18:02:32.858 [http-nio-8239-exec-6] ERROR c.a.b.c.exceptionHandler.CodeBaseExceptionHandler:69 - Handler dispatch failed...

    Java 高级特性.doc

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println("begin " + method.getName()); Object retval = method....

    How to invoke Java web service in ASP.net using C#.zip

    How to invoke Java web service in ASP.net using C#.zip

    java业务层框架开发ibatis(java源码)

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null;} public Statement createStatement() throws SQLException { return null;} public PreparedStatement ...

    深入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...

    JNI--java调用不同平台的动态链接库,dll,so,完美,全教程

    然后再在 Java 中载进这个适配器 dll/so ,再编写 Java?? native 函数作为 dll 中函数的代理。 经过 2 个繁琐的步骤才能在 Java 中调用本地代码。 因此,很少有 Java 程序员愿意编写调用 dll/.so 库中的原生函数的 ...

Global site tag (gtag.js) - Google Analytics