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. elasticsearch索引目录设置

    path.data and path.logs If you are using the .zip or .tar.gz archives, the data and logs directories ...

  2. 【xsy1154】 DNA配对 FFT

    题目大意:给你一个字符串$s$和字符串$w$,字符集为${A,T,C,G}$,你要在字符串$s$中选出一个与$w$长度相同的子串,使得这两个串的差异度最小. 两个字符$c1$,$c2$的差异度为给定的 ...

  3. WebDriverAPI(3)

    获取页面的Title属性 被测网址http:http://www.baidu.com Java语言版本的API实例代码 String url = "http://www.baidu.com& ...

  4. Backing Up and Restoring HBase Data

    There are two strategies for backing up HBase:1> Backing it up with a full cluster shutdown2> ...

  5. DotNetOpenAuth 使用指南

    这几天一直在研究DotNetOpenAuth,源码处处是坑啊!写此文只为大家更顺利掌握DotNetOpenAuth使用方法,尽量少走弯路. 说明一下:我的环境是Win7 64   VS2015 upd ...

  6. Check类中的incl、union,excl,diff,intersect

    定义一些类,这些类之间有父子关系,如下: class Father{} class Son1 extends Father{} class Son2 extends Father{} class To ...

  7. 《垃圾回收的算法与实现》——增量式垃圾回收与RC Immix算法

    增量式垃圾回收 为了控制最大暂停时间,通过逐渐推进垃圾回收即垃圾回收与mutator交替执行. 三色标记算法 以标记-清除算法为例使用三色标记算法. 利用降低吞吐量来缩短最大停顿时间. 基础 将GC中 ...

  8. Web服务端性能提升实践

    随着互联网的不断发展,日常生活中越来越多的需求通过网络来实现,从衣食住行到金融教育,从口袋到身份,人们无时无刻不依赖着网络,而且越来越多的人通过网络来完成自己的需求. 作为直接面对来自客户请求的Web ...

  9. elasticsearch插件安装之--linux下安装及head插件

    /** * 系统环境: vm12 下的centos 7.2 * 当前安装版本: elasticsearch-2.4.0.tar.gz */ 安装和学习可参照官方文档: 1, 安装 # 下载, 获取不成 ...

  10. node.js获取url中的各个参数

    实例代码test.js var http=require('http'); var url=require('url'); var querystring=require('querystring') ...