Java方法的参数传递方式为: 值传递

对于基本数据类型作为参数传递时, 是"按值传递", 这点都认识很清楚. 但是, 当对象或者说引用作为参数传递, Java 的参数传递方式是"按值传递", 还是"按引用传递", 对于新接触Java的朋友来说, 可能有点难以分清. 甚至可能有些用过一段时间的朋友对此也有争议.

首先我观点是Java参数传递方式只有一种, 就是按值传递.

先看一个代码, 如下:

public class Word {

    public Word(String word) {
this.str = word;
} public String str; public String getStr() {
return str;
}
}
public class Tester {

    public static void main(String[] args) {
Tester tester=new Tester();
Word firstWord=new Word("Hello WOrld");
System.out.println("新建对象:"+firstWord.str);
tester.changeData(firstWord);
System.out.println("执行changeData后,原对象的str属性值"+firstWord.str);
} public void changeData(Word word){
word.str="Hello Kitty";
System.out.println("更改后的值:"+word.getStr());
}
}

运行后输出为:

新建对象:Hello WOrld
changeData方法体中更改后值:Hello Kitty
执行changeData后,FirstWord对象的str属性值Hello Kitty

这里将类 firstWord 传入后, changeData 方法把 Hello World 改成了 Hello Kitty, 并且在方法体中调用 getStr方法获得确实改称了 Hello Kitty, 回到 main 函数中, 发现 firstWord 中的str 也是 Hello Kitty.

这给人感觉是把 firstWord 对象本身传给了changeData方法, 于是在方法中对word的修改后相当于是对 firstWord 的修改. 可能很多时候会想到用这个方式来  "修改"变量: 把对象作为实参传递给某个方法, 通过在方法中对形参变量的操作来改变原对像的值, 调用结束后传参的对象改变, 特别是需要有多个返回值时.  但是这样使用时要要小心了,

因为实际二者是相互独立的, 是两个不同的变量,

如图所示,假如Hello World对象地址是 @123,两个引用变量存的是这个地址:

请看下面代码:

public class Tester {

    public static void main(String[] args) {
Tester tester=new Tester();
new Word("ff");
Word firstWord=new Word("Hello WOrld");
System.out.println("新建对象:"+firstWord.str);
tester.changeData(firstWord);
System.out.println("执行changeData后,FirstWord对象的str属性值"+firstWord.str);
} public void changeData(Word word){
word.str="Hello Kitty";
System.out.println("changeData方法体中更改后值:"+word.getStr());
word.str=null;
}
}

我们在最后一行加了一句 : word.str=null; 输出结果:

新建对象:Hello WOrld
changeData方法体中更改后值:Hello Kitty
执行changeData后,FirstWord对象的str属性值null

从代码运行结果和上图可以看到, 把 word 置成 null 后, 并不会影响到 firstWord , firstWord 依然存在, 这就说明, 二者是独立的 两个 不同 变量.

可能你会说, 我又一般又不会在changeData 函数体内设置成 null, 上面方法还是没啥关系. 但请间下面的一个情形, 可能一不小心就会犯类似错误:

public class Tester {

    public static void main(String[] args) {
Tester tester=new Tester();
new Word("ff");
Word firstWord=new Word("Hello WOrld");
System.out.println("新建对象:"+firstWord.str);
tester.changeData(firstWord);
System.out.println("执行changeData后,FirstWord对象的str属性值"+firstWord.str);
} public void changeData(Word word){
word= new Word("Hello Kitty");
System.out.println("changeData方法体中更改后值:"+word.getStr());
}
}

可能有些想法是, 把 firstWord 传给了 形参 word, 接着 把word指向一个新建的 Hello Kitty, 那么firstWord 应该也指向了 Hello Kitty.

看看程序输出结果:

新建对象:Hello WOrld
changeData方法体中更改后值:Hello Kitty
执行changeData后,FirstWord对象的str属性值Hello WOrld

发现实际并不是changeData 方法后, firstWord和word都指向 Hello Kitty, firstWord 依然指向 Hello World, 这时, 如果对Java传参了解不够, 认为传递对象进函数, 在函数内形参进行设计好的算法操作后,可以获得改变后的对象.  在这里, 就发现并不能实现这样愿望.

如果认为 Java对象作参数时,是引用传递, 当代码写长后, 可能一不小心就会出现上面类似的错误. 而且这样错误时通常还很难察觉出来.

如上面所述, 实际上对象作为参数传递时, 传递的仍然是 "值":

在mian函数中, new Word("Hello WOrld") 语句创建了 firstWord对象, 并且定义了叫 firstWord 的"引用变量" 来指向该对象(firstWord引用变量所存的是new Word("Hello WOrld") 对象的地址, 这和基本数据类型int是一样的, 只不过 int 存数值, 引用变量存地址). 传参时, 实际是把firstWord变量所存的地址值 复制了一份, 给了形参 word, 这时候他们都指向了同一个对象, 因此在 word 中更改的对象与 firstWord指向的是同一个对象, 所以这时更改会影响 firstWord. 但是word 和 firstWord 是相互独立的两个变量, 这和 C 语言中引用传递时指针的机制是不同的.

如下图所示:

Java方法的参数传递方式为: 值传递的更多相关文章

  1. JAVA方法中参数到底是值传递还是引用传递

    当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递? 答:是值传递.Java 语言的参数传递只有值传递.当一个实例对象作为参数被传递到方法中时,参 ...

  2. java方法参数传递方式只有----值传递!

    在通常的说法中,方法参数的传递分为两种,值传递和引用传递,值传递是指将实际参数复制一份传递到方法中, 在方法中的改动将不会影响到实际参数本身,而引用传递则是指传递的是实际参数本身,在方法中的改动将会影 ...

  3. java中方法传入参数时:值传递还是址传递?

    JAVA中的数据类型有两大类型: ① 基本数据类型:逻辑型(boolean).文本型(char).整数型(byte.short.int.long).浮点型(float.double) ② 引用数据类型 ...

  4. 关于Java方法的参数

    刚好看到C++的函数这块,说C++中除了引用类型的形参,其他都是实参的副本(个人总结). 隐约记得Java中方法的参数也是这么回事,于是手动测试一番. 结果 Java中方法的参数都是值传递,哪怕是引用 ...

  5. 辨析Java方法参数中的值传递和引用传递

    小方法大门道 小瓜瓜作为一个Java初学者,今天跟我说她想通过一个Java方法,将外部变量通过参数传递到方法中去,进行逻辑处理,方法执行完毕之后,再对修改过的变量进行判断处理,代码如下所示. publ ...

  6. Java里方法的参数传递方式

    Java里方法的参数传递方式只有一种:值传递. Java中参数传递的都是参数值 下面从两个维度来看 1.传递的参数是8种基本数据类型 这个比较好理解,8种基本数据类型,作为参数时,可以理解为原来的一个 ...

  7. Java调用函数传递参数到底是值传递还是引用传递

    今天翻看微信上有关Java技术的公众号时,看到了一篇关于Java中值传递的问题,文章讨论了在Java中调用函数进行传参的时候到底是值传递还是引用传递这个面试时会问到的问题.之前也接触过类似的问题,但只 ...

  8. Java当中的内存分配以及值传递问题内存解析

    首先必须说明作为Java程序员对于内存只要有大致的了解就可以了,如果你对Java当中的某一个知识点在不需要分析内存分配过程的情况下可以掌握,那就大可不必去研究内存.如果你对知识点已经掌握,那么你应该把 ...

  9. Java 函数参数传递方式详解 分类: Java Game 2014-08-15 06:34 82人阅读 评论(0) 收藏

    转:http://zzproc.iteye.com/blog/1328591 在阅读本文之前,根据自己的经验和理解,大家可以先思考并选择一下Java函数的参数传递方式:  A. 是按值传递的?  B. ...

随机推荐

  1. klee的docker镜像中没有gcc环境

    sudo apt-get update 密码 klee sudo apt-get install gcc export LD_LIBRARY_PATH=/home/klee/lib/:$LD_LIBR ...

  2. DIV居中的几种方法

    1. body{ text-align:center; } 缺点:body内所有内容一并居中 2. .center{ position: fixed; left: 50%; } 缺点:需要设置posi ...

  3. Linux CentOS7系统中ssh的用法

    大家都知道,公司买上服务器,不可能实时在线操作虚拟机,也没有那个时间和精力登录到公司的云服务商官网进行操作,一来不安全,二来也效率不高. 如果是购买的虚拟主机,你可以使用ftp进行本地程序文件传输和从 ...

  4. jdbc调试sql语句方法

    在main命令行输入三个参数到oracle 的 dept2表(自己建的 和dept一样(deptno,dname,loc)),插入到数据库中去.通过本例子,学习在java里调试sql的方法. 写完sq ...

  5. Windows下PATH等环境变量详解

    在学习JAVA的过程中,涉及到多个环境变量(environment variable)的概念,如PATH.正确地配置这些环境变量,是能够顺利学习.开发的前提.而经常出现的问题是:有的学习者能够按照提示 ...

  6. 解决linux安装软件依赖的曲线救国方案

    相信大家在一台无法连接外网的linux上安装软件时,对于软件依赖的安装,都会特别头疼,因为软件依赖的安装,不论是其数量,还是安装的复杂度都比软件本身要高出一个维度! 今天就和大家分享一个,解决linu ...

  7. MySQL decimal unsigned 更新负数不报错却为0

    今天在验证接口的并发问题时,把之前通过 redis 解决的并发压力转移到 mysql 上(redis 在 set 保存数据和数据过期需要去向数据库获取时存在时延,会存在空挡造成大并发多插入数据的风险: ...

  8. mysql查看权限的命令

    mysql查看用户权限的命令 1.这里用来查看用户存储过程: show grants for 用户; eg: show grants for root@'localhost';#这样就会把root用户 ...

  9. ArrayList的subList方法

    参考博文使用java.util.List.subList时最好小心点 List接口中定义: List<E> subList(int fromIndex, int toIndex); 英文注 ...

  10. spring中获取applicationContext

    常用的5种获取spring 中bean的方式总结: 方法一:在初始化时保存ApplicationContext对象代码:ApplicationContext ac = new FileSystemXm ...