java中入参_JAVA传参
概述
java中的参数传递问题可以根据参数的类型大致可以分为三类:传递基本类型,传递String类型,传递引用类型,至于最终是否可以归纳为值传递和引用传递,根据每个人的理解不同,答案不同,此处不做强调。
传递基本类型
public class Test1 {
public static void main(String[] args) {
int n = 3;
System.out.println("Before change, n = " + n);
changeData(n);
System.out.println("After changeData(n), n = " + n);
}
public static void changeData(int n) {
n = 10;
}
}
结果:Before change, n = 3
After changeData(n), n = 3
解析(比较简单不结合字节码分析):
1.线程调用main方法,创建栈帧A,局部变量表有n=3
2.main方法中调用changeDate方法,传入参数n=3,线程创建栈帧B,将10赋给n后,局部变量表有n=10
3.changeDate方法执行完毕,栈帧B弹出,输出栈帧A中n的值为3
传递String类型
public class Test2 {
public static void main(String[] args) {
String str = new String("String");
System.out.println("Before change, str = " + str);
changeData(str);
System.out.println("After changeData(n), str = " + str);
}
public static void changeData(String str) {
str = "newString";
}
}
结果:Before change, str = String
After changeData(n), str = String
指令码为(将上述代码两条输出语句删除后进行编译,反汇编,为了突出主要过程):
public static void main(java.lang.String[]);
0: new #2 // class java/lang/String
3: dup
4: ldc #3 // 返回常量池中字符串的引用,并且入栈
6: invokespecial #4 // Method java/lang/String."":(Ljava/lang/String;)V
9: astore_1
10: aload_1
11: invokestatic #5 // Method changeData:(Ljava/lang/String;)V
14: return
public static void changeData(java.lang.String);
0: ldc #6 // 返回常量池中字符串的引用,并且入栈
2: astore_0
3: return
}
解析: 1.new,dup,Idc,invokespecial,astore_1:在栈帧A中完成了实例化一个String对象,并将一个指向该对象的引用存入了局部变量表的操作
2.aload_1,invokestatic:调用changeDate方法,传入引用,创建栈帧B
3.Idc,astore_0,return:在栈帧B中完成了将指向常量池中"newString"字符串的引用压入操作数栈并且将该引用存入局部变量表的操作,之后栈帧B弹出
4.栈帧A局部变量表中那个引用依然指向String对象,其值依然为String
传递引用类型
public class Test3 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello ");
System.out.println("Before change, sb = " + sb);
changeData(sb);
System.out.println("After changeData(n), sb = " + sb);
}
public static void changeData(StringBuffer strBuf) {
strBuf.append("World!");
}
}
结果:Before change, sb = Hello
After changeData(n), sb = Hello World!
指令码为(将上述代码两条输出语句删除后进行编译,反汇编,为了突出主要过程):
public static void main(java.lang.String[]);
0: new #2 // class java/lang/StringBuffer
3: dup
4: ldc #3 // String Hello
6: invokespecial #4 // Method java/lang/StringBuffer."":(Ljava/lang/String;)V
9: astore_1
10: aload_1
11: invokestatic #5 // Method changeData:(Ljava/lang/StringBuffer;)V
14: return
public static void changeData(java.lang.StringBuffer);
stack=2, locals=1, args_size=1
0: aload_0
1: ldc #6 // String World!
3: invokevirtual #7 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/ StringBuffer;
6: pop
7: return
}
解析(说明下和String传参区别的地方):
在changeDate方法中有了aload操作,也就是将传递来的引用压入了操作数栈,并且之后的Idc,invokevirtual操作说明对该引用指向的对象进行了相关操作,很显然在栈帧B弹出时,栈帧A局部变量表中的引用指向的对象发生了变化。
总结
回头看一下:综合来看基本变量和String变量传参,对传入参数进行改变的时候,都没有用到传入的参数值(也就是没有aload操作),直接将基本类型值或者常量池中字面量引用赋值给变量。怎么看都有些别扭,因为String本质上是一个类和基本类型中终究是不同的,我的理解是:String类既然设计成final类,暗示string变量的复用带来的正面效果大于由于不能改变String变量而必须存入一个新的string字符串的负面效果,那么为了复用,对于String变量的赋值语句在编译时便进行了特殊处理,在常量池中找是否已经存在该字符串,如果有,返回引用,达到复用的目的,如果没有,将字符串放入常量池返回该引用为了下次复用。而对于其他引用变量传参,当栈帧B要对传入参数进行改变的时候,都会进行aload操作,由于jvm是基于栈的字节码执行,aload的参数只能是栈帧A中引用的复制,这点区别于C,由于C是基于寄存器的操作,其指针传递,操作是的是指针变量本身,可以用一个经典的引用交换实例区分,网上有举例,不在累述,以上。
java中入参_JAVA传参相关推荐
- mybatis java传参_[Java教程]Mybatis批量和传参
[Java教程]Mybatis批量和传参 0 2014-07-31 04:00:12 MyBatis中批量插入 方法一: resultType="java.lang.String" ...
- java代码发送请求并传参_如何优化您的请求请求并使代码审核人员满意
java代码发送请求并传参 Imagine reading a novel, but having the chapters sliced up and reordered alphabeticall ...
- ajax redirectattributes 使用,Spring中RedirectAttributes对象重定向传参
Spring3中的FlashAttribute 为 了防止用户刷新重复提交,save操作之后一般会redirect到另一个页面,同时带点操作成功的提示信息.因为是Redirect,Request里 的 ...
- js中使用进行字符串传参
在js中拼接html标签传参时,如果方法参数是字符串需要加上引号,这里需要进行字符转义 <a href='javascript:addMenuUI("+"\"&qu ...
- MySQL在脚本中执行传参数_ZZW_shell脚本中的调用MYSQL传参及注意的问题
[oracle@ip9140 db_pcc]$ cat zzw_cc.sh #!/bin/bash z_user='pcc_csuser22' z_pass='pcc_csuser22' z_db=' ...
- quartz定时任务中如何给MyJob传参
quartz定时任务中如何给MyJob传参 在调度服务中使用语句传参 在myjob中接收参数 在调度服务类中,定义一个私有变量,并添加setter方法用于赋值.这里的私有变量就是需要向myjob传递的 ...
- jeecg-boot中popup实现动态传参
jeecg-boot中popup实现动态传参 环境: 功能实现: 后话: 环境: 最近任务是基于jeecg-boot框架的,用的是jeecg-boot V2.4.0版. 功能实现: 有表"p ...
- vue动态路由传参---query传参和params传参
当一个页面跳转到另一个页面时,组件结构相同,只是内容不同且地址栏后缀不同 ,这个地址栏的后缀就是参数,根据不同参数渲染不同的内容,这个跳转就叫路由传参. 当项目中组件间通过路由跳转,有时,我们需要传递 ...
- JAVA中是传值还是传引用?回答KEZHANG问题
首先,推荐对Java有一定理解的同仁一本书<Practical Java>.在<Practical Java>中也有一个章节介绍Java中关于传值和传引用的问题,堪称经典. & ...
- java语言 文件上传,java中实现文件上传的方法
java中实现文件上传的方法 发布时间:2020-06-19 10:29:11 来源:亿速云 阅读:86 作者:Leah 这篇文章给大家分享的是java中实现文件上传的方法,相信大部分人都还没学会这个 ...
最新文章
- android gpio操作
- git 回退远端master分支版本
- vue父组件使用子组件函数,vue子组件使用父组件函数
- Mybatis笔记——Mybatis入门
- 计算机通信事业单位专业知识点,事业单位计算机专业知识招考大纲
- 新手也能看懂的 SpringBoot 异步编程指南
- 杭电 1242题(深度优先搜索)
- 常见不等式考察(一)——Jensen不等式
- GLES3.0中文API-glMemoryBarrier
- three doors
- 最终服务器的信息接收及响应,ehlo详解
- 水面渲染-浮力的一种实现
- 学数据分析,这些常用术语少不了!
- OpenNI2的下载与安装
- linux基础内容,掌握这些基本可以流畅的使用linux系统
- OllyDbg分析crackme-AcidBurn
- php将一组数从小到大排序,php数组排序从小到大函数
- Android中的IPC方式
- Android第三方流式布局FlowLayout简单实用(搜索历史记录)
- android适配手机与平板,关于平板适配问题