java中的参数(java 对象传递)是怎样传递的

Java中函数的参数为类对象时,到底怎么传递
[问题点数:10分,结帖人WuBill]
本版专家分:1406
结帖率 100%
CSDN今日推荐
本版专家分:404
本版专家分:32939
2008年9月 Java大版内专家分月排行榜第二2008年8月 Java大版内专家分月排行榜第二
2008年10月 Java大版内专家分月排行榜第三
本版专家分:7
本版专家分:213
本版专家分:2222
本版专家分:132
本版专家分:1406
本版专家分:181
本版专家分:802
本版专家分:3231
本版专家分:1406
本版专家分:3436
匿名用户不能发表回复!|
其他相关推荐Java:关于值传递你需要了解的事情 - 为程序员服务
Java:关于值传递你需要了解的事情
我们都知道,在Java中,方法的
传递永远都是指值传递。让我们来看一看基本类型和集合的参数传递在内存中是如何体现的。
原文链接:
://dzone.com/articles/
-pass-by-reference-or-pass-by-
在讨论Java中参数是如何传递之前,我们有必要先弄清楚Java的变量(主要指的是基本类型和对象)是怎么存储在内存中的。
基本类型一般都存储在堆栈中;对于Java对象,实际的对象
存储在堆中,而对象的指针(指向推中的对象)存储在堆栈中。
1.传值 vs 传引用
“传值”和“传引用”分别是什么意思:
传值:当方法参数是值传递时,意味着原参数的一个拷贝被传到了参数内部而不是原始参数,所以任何对于该参数的改变都只会影响这个拷贝值。
传引用:当方法参数是引用传递时,意味着原始参数的引用或者说指针被传递到了方法内部,而不是这个原始参数的内容。
2.在Java中参数是怎么传递的
在Java中,不管原始参数的类型是什么,参数都是按值传递的。每次当一个方法被执行的时候,在堆栈中就会为每个参数创建一个拷贝,这个拷贝会被传递到方法内部。
如果原始参数是基本类型,那么在堆栈中创建的便是这个参数的简单拷贝
如果原始参数不是基本类型,那么在堆栈中创建的便是指向真正对象数据的新的引用或指针。这个新的引用被传递到方法内部(在这种情况下,有2个引用指向了同一个对象数据)
3.解决疑惑
在接下来的示例中,我们通过往方法中传递不同类型的参数(基本类型,包装类,
,自定义类),在方法执行完成后去检查他们是否被修改了来尝试证明“在Java中参数传递永远是值传递”。
基本类型参数
public static void main(String[] args) {
int x = 1;
int y = 2;
System.out.print("Values of x & y before primitive modification: ");
System.out.println(" x = " + x + " ; y = " + y );
modifyPrimitiveTypes(x,y);
System.out.print("Values of x & y after primitive modification: ");
System.out.println(" x = " + x + " ; y = " + y );
private static void modifyPrimitiveTypes(int x, int y)
Values of x & y before primitive modification:
x = 1 ; y = 2
Values of x & y after primitive modification:
x = 1 ; y = 2
x,y这2个参数是基本类型,所以存储在堆栈中。当调用modifyPrimitiveTypes()方法时,在堆栈中创建了这2个参数的拷贝(我们就叫它们w,z),实际上是w,z被传递到了方法中。 所以原始的参数并没有被传递到方法中,在方法中的任何修改都只作用于参数的拷贝w,z
public static void main(String[] args) {
Integer obj1 = new Integer(1);
Integer obj2 = new Integer(2);
System.out.print("Values of obj1 & obj2 before wrapper modification: ");
System.out.println("obj1 = " + obj1.intValue() + " ; obj2 = " + obj2.intValue());
modifyWrappers(obj1, obj2);
System.out.print("Values of obj1 & obj2 after wrapper modification: ");
System.out.println("obj1 = " + obj1.intValue() + " ; obj2 = " + obj2.intValue());
private static void modifyWrappers(Integer x, Integer y)
x = new Integer(5);
y = new Integer(10);
Values of obj1 & obj2 before wrapper modification: obj1 = 1 ; obj2 = 2
Values of obj1 & obj2 after wrapper modification: obj1 = 1 ; obj2 = 2
包装类存储在堆中,在堆栈中有一个指向它的引用
当调用modifyWrappers()方法时,在堆栈中为每个引用创建了一个拷贝,这些拷贝被传递到了方法里。 任何在方法里面的修改都只是改变了引用的拷贝,而不是原始的引用
P.S: 如果方法中的表达式为x += 2,x值得改变也不会影响到方法外部,因为包装类是immu
le类型的。当他们的state变化时,他们就会创建一个新的
。如果你想了解更多关于immutable类,可以阅读 How to create an immutable class in Java 。字符串类型和包装类相似,所以以上的规则对于字符串也有效。
public static void main(String[] args) {
List&Integer& lstNums = new ArrayList&Integer&();
lstNums.add(1);
System.out.println("Size of list before List modification = " + lstNums.size());
modifyList(lstNums);
System.out.println("Size of list after List modification = " + lstNums.size());
private static void modifyList(List&Integer& lstParam)
lstParam.add(2);
Size of list before List modification = 1
Size of list after List modification = 2
当我们创建一个ArrayList或任意集合,在堆栈中便会创建一个指向堆中多个对象的引用。当modifyList()被调用时,一个引用的拷贝被创建中传递到了方法中。现在有2个引用指向了真正的对象数据,其中任何一个引用的数据改变会影响到另一个。
在方法中,当我们调用
lstParam.add(2)
时,一个Integer对象在堆中被创建,添加到了现有的list对象。 所以原始的list引用可以看见这次修改,因为2个引用都指向了内存中的同一个对象
自定义对象
public static void main(String[] args) {
Student student = new Student();
System.out.println("Value of name before Student modification = " + student.getName());
modifyStudent(student);
System.out.println("Value of name after Student modification = " + student.getName());
private static void modifyStudent(Student student)
student.setName("Alex");
Value of name before Student modification = null
Value of name after Student modification = Alex
student对象在堆中被创建,在堆栈中存储着指向它的引用。当调用calling modifyStudent(),在堆栈中创建了这个引用的拷贝,传递到了方法中。
所以任何对这个对象属性的修改会影响原始的对象引用
在Java中,参数都是按值传递的。被传递到方法中的拷贝值,要不就是一个引用或一个变量,取决于原始参数的类型。从现在开始,下面的几条规则将帮助你理解方法中对于参数的修改怎么影响原始参数变量。
在方法中,修改一个基础类型的参数永远不会影响原始参数值。
在方法中,改变一个对象参数的引用永远不会影响到原始引用。然而,它会在堆中创建了一个全新的对象。(译者注:指的是包装类和immutable对象)
在方法中,修改一个对象的属性会影响原始对象参数。
在方法中,修改集合和Maps会影响原始集合参数。
://www.importnew.com/29023.html
本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。
PS:推荐一个微信公众号: askHarries 或者qq群:,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
转载请注明原文出处:
追心中的海,逐世界的梦
原文地址:, 感谢原作者分享。
您可能感兴趣的代码有句话说的很对,会用是一回事,深入理解又是另一回事了 ╮( ̄▽ ̄”)╭
Java技术——Java中的参数传值方式
昨天10号晚上迎来了今日头条视频面试三连击(Android开发实习生),每场都50都分钟,而且问的问题有些确实有点难(头条的工程师水平确实有点高,面BAT的时候都没这么大压力),不过今日头条是我见过招聘效率最高的公司,第一场面试结束后面试官会让你不要离开视频间,等待HR通知,一般HR在10分钟你就会打电话告知你一面过了,马上开始第二场面试。就这样进行了三轮视频面试,结果差强人意,三面都通过了,并且获得了秋招终面直通卡。不废话了,这篇文章主题就是一面中的一道面试题。 1.
你觉得下面程序会输出什么public static void change(String s) {
s = “123”;
public static void main(String args[]) {
String s = “abc”;
change(s);
System.out.println(s);
面试官写下了这段代码,问我s会输出什么。我想起了各种排序算法直接把一个int数组array,通过参数传递给一个方法,在方法里完成数据的移动后,直接在main()函数中输出array[]中的值就是修改过的。所以我回答说,那应该输出123吧。然后面试官说,不对,是输出abc,你觉得原因是什么。我想了想回答说,String是final的,所以值是不变的。接着面试官写下了如下代码:public static void main(String[] args) {
MyClass myClass = new MyClass();
change(myClass);
System.out.println(myClass.val);
private static void change(MyClass myClass) {
myClass = new MyClass();
myClass.val = 2;
public static class MyClass{
int val = 1;
问我MyClass类不是final的,但为什么这里还是会输出1。我有点被问懵了,其实后来面试结果又仔细看一下,是自己忽略掉了第八行代码,其实把第八行代码注释掉,肯定就输出2了。2.
Java参数传值2.1
值传递先从一个例子说起:public static void change(int i, int j) {
public static void main(String[] args) {
change(a,b);
System.out.println(a);
System.out.println(b);
值传递是指方法调用时,实际参数把它的值传递给对应方法的形参,如change()方法中i和j,也在内存空间中分配了存储单元,这样形参在change()方法中的改变不会影响实际参数的值。值传递的数据类型包括,八种基本数据类型和String。2.2
引用传递值传递的数据类型包括,八种基本数据类型和String,八种数据类型还比较好理解,比如2.1中的int,但是String并不是基本数据类型,这要怎么理解呢。比如下面这个例子。public class Example {
String str = new String("abc");
char[] ch = { 'a', 'b', 'c' };
public static void main(String args[]) {
Example ex = new Example();
ex.change(ex.str, ex.ch);
System.out.println(ex.str);
System.out.println(ex.ch);
public void change(String str, char ch[]) {
//ch = new char[]{'a','b','c'};
str = "change";
ch[0] = 'c';
这个例子的输出为:abc
要知道String和char数组都是引用类型,不是基本类型。当我们把str作为参数传入方法后,会新建另一个变量,已经不是原来的变量了,但是他们指向的数据区域都一样,所以如果你在方法中改变了str指向的数据区域,即执行str = "change",那也只是改变新建的另一个变量所指向的数据区域,即指向一个新对象"change",str仍然指向原来的数据区域。所以会输出abc。 但是对于char数组的例子呢,即对象类型,也就是Object的子类(除了String),是把ch的引用传递进来,即引用传递。这样里面和外面的ch都指向了相同的数据区域,执行ch[0] = 'c',就会把这个数据区域里的第一个字符改成c,并没有改变内部ch的数据地址,所以这个修改也会反映到外部的ch。所以会输出cbc。如果你改变了内部ch所指向的数据区域,即把上面代码中注释的那一行打开,即执行ch = new char[]{'a','b','c'},这样ch已经指向一个新的数据区域。输出的结果肯定也就是abc了。 这样在1中面试官给的两段代码也就很容易解释了。3
两种数据传递总结值传递和引用传递的本质区别在于是否在传递的时候进行对象的内存拷贝。基本类型是由于在JVM中存储区域不同于普通对象所以传递前会拷贝,传递的是拷贝后的值,但是对象在传递的时候不拷贝,直接传“引用值”,指向同一片对象堆内存区域,当然要注意String这种特殊情况。
没有更多推荐了,> 问题详情
Java中方法的参数传递是【 】调用,方法不能改变参数值,但可以改变变量值,两个对象之间的参数字段
悬赏:0&答案豆
提问人:匿名网友
发布时间:
Java中方法的参数传递是【 】调用,方法不能改变参数值,但可以改变变量值,两个对象之间的参数字段不能相互交换。请帮忙给出正确答案和分析,谢谢!
您可能感兴趣的试题
1面向对象的语言将客观世界都看成由各种对象组成,共同特征和行为的对象组成类,类是变量和【 】的集合体。请帮忙给出正确答案和分析,谢谢!2正面向对象方法学中,直接反映了用户对目标系统的要求的模型是【 】。请帮忙给出正确答案和分析,谢谢!3下列程序实现的功能是当按下键盘时,在Applet中通过painnt()方法,在(50,50)位置处显示出按下的键的名称。在横线处填写正确的语句。 import java.awt.*; import java.awt.event.*; import java.applet.*; public class Test7 extends Applet { String str=" "; public void init() { addKeyListener (new KeyAdapter() { public void keyPressed(KeyEvent ke) { 【 】; repaint(); } }); requestFocus(); } public void paint(Graphics g) { g.drawString("你按下的键是:"+str,50,50); } { str=-ke.getKeyText(ke.getKeyCode())请帮忙给出正确答案和分析,谢谢!4根据一个模式串pattemStr,将表达式编译成模式对象的语句是【 】。请帮忙给出正确答案和分析,谢谢!
我有更好的答案
请先输入下方的验证码查看最佳答案
图形验证:
验证码提交中……
每天只需0.4元
选择支付方式
支付宝付款
郑重提醒:支付后,系统自动为您完成注册
请使用微信扫码支付(元)
支付后,系统自动为您完成注册
遇到问题请联系在线客服QQ:
恭喜你被选中为
扫一扫-免费查看答案!
请您不要关闭此页面,支付完成后点击支付完成按钮
遇到问题请联系在线客服QQ:
恭喜您!升级VIP会员成功
提示:请截图保存您的账号信息,以方便日后登录使用。
常用邮箱:
用于找回密码
确认密码:我的这一生
java中把对象作为参数传递的理解
今天在写程序时,发现一个问题:
Date olissuePublishDate = o.getDate("olissue_publish_date");
isSpecialDate(olissuePublishDate);
map.put("olissue_publish_date", olissuePublishDate);
下面这个方法是:要是日期为,就把其置为空。
* 特殊判断处理
* issuePublishDate
* 日下午1:25:48
public static Date isSpecialDate(Date issuePublishDate) {
if(issuePublishDate == null){
return null;
if(DateUtil.compare(issuePublishDate, DateUtil.stringToDate("", "yyyy-MM-dd")) == 0){
issuePublishDate = null;
return issuePublishD
我是希望通过方法isSpecialDate来改变外面olissuePublishDate的值
结果发现并没与成功:
map.put("olissue_publish_date", olissuePublishDate);
得到的数据,还是,而不是null。
对象 – 引用传递
因为在我的记忆里,对象是按照引用传递的,所以在调用这个isSpecialDate(olissuePublishDate);方法时,如果方法内部改变了对象,那么外部的也会得到改变。
网上查询资料后,才知道java本质上只有按值传递;
只有一种参数传递机制 – 按值传递
无论引用类型或基本类型,当作为参数传递给一个方法时,两种类型都是按值传递的。
按值传递意味着当将一个参数传递给一个方法时,方法接收的是原始值的一个副本。
Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
只不过,当把对象作为参数传递时,可以通过该副本引用改变该对象的的属性。
而我上面程序在方法里issuePublishDate =这里已经对变量重新赋值了。此时的变量issuePublishDate已经不再是参数传进来的那个引用啦!所以自然就不会影响外面的原值。
参考地址:
没有更多推荐了,

我要回帖

更多关于 java对象作为参数 的文章

 

随机推荐