今天我们来讲讲一个在学习中容易误解的问题,面试中也偶尔问到,java方法调用时到底是值传递还是引用传递?

首先,请大家来做一个判断题,下面的3个问题是否描述正确

1. java基本数据类型传递是值传递,引用数据类型是引用传递

2. java都是引用传递

3. 方法调用时传的是数据值就是指传递,传的是地址就是引用传递

我们暂且不直说上面3个问题的正确性,下面,我们通过几个测试案例来测试一下参数传递

1. 基本数据类型当作参数

public class test1 {
public static void main(String[] args) throws Exception {
int a = 10;
change(a);
System.out.println("a = " + a); }
public static void change(int s) {
s = 20;
System.out.println("s = " + s);
}
}

 运行结果:  方法执行后,没有改变原有a的值

s = 20
    a = 10

2. 引用类型当作参数

public class Student {
private String name; //姓名
Student(String name){
this.name = name;
} public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} } public class Test1{

   public static void main(String[] args) throws Exception {
      Student s = new Student("haly");
      change(s);
      System.out.println("s = " + s.getName());

  }

public static void change(Student x) {
         x.setName("wuwu");
         System.out.println("x = " + x.getName());
   }

}

运行结果: 方法执行后,改变了原来s的值

x = wuwu
s = wuwu

看到这里,很多同学就觉得问题1答案是正确的, java基本数据类型传递是值传递,引用数据类型是引用传递,但是真的是这样吗?

这里我可以提前透露下答案,上面这个测试之所以改变了原来实参s里面的值,是因为我们传递到方法的都是实参对象的一个拷贝,x对象是s对象引用的一个拷贝,

所以x和s都是指向同一块内存地址,改变x里面的值,相当于改变s的值,因为传的是对象引用的拷贝,而不是对象引用本身,所以是值传递。

如果不好理解,我给大家举个例子:

我有一辆车,我自己有一把车钥匙,有一天我的女朋友想要开车,我就配制了一把车钥匙给她,这时候,相当于方法调用,传递了一把钥匙的拷贝给她。

她在钥匙上刻字,对我的钥匙是没有影响的,但是她拿钥匙打开车,将我的车坐垫换了,我开这辆车的时候,车坐垫的确是换掉了,这是同一个道理。

如果还不清楚,我用两张图,分别表示案例1和案例2的值传递:

                            

案例1                                                                                               案例2

如果大家还不好理解,下面我就写一个案例3,让大家更加清晰的看出,java是值传递

3. 引用类型当作参数

public class Test1 {
public static void main(String[] args) throws Exception {
Student s1 = new Student("小张");
Student s2 = new Student("小李");
Test1.swap(s1, s2);
System.out.println("s1:" + s1.getName() + ",s2:" + s2.getName()); }
public static void swap(Student x, Student y) {
Student temp = x;
x = y;
y = temp;
System.out.println("x:" + x.getName() + ",y:" + y.getName());
} }

运行结果:

x:小李,y:小张
s1:小张,s2:小李

通过测试3的代码,我们可以看出,在方法中交换了两个参数的值,但是原来的值并没有交换,如果是引用传递的话,我们操作的都是实参本身的引用,按理也会交换的。

下面,我们通过一个图在仔细思考一下答案:我们交换了x和y对象的引用,对原来的s1和s2并没有影响。

通过以上代码及图描述,我们可以得出如下2个结论:

1. 如果我们传递的实参是对象引用的拷贝,就是值传递,如果我们传递的实参是引用本身,就是引用传递。

2. 在java中,不管基本数据类型,还是引用类型,都是值传递。

如有不正确的地方,欢迎大家批评指出,一起进步~~

java到底是引用传递还是值传递?的更多相关文章

  1. 理解Java中的引用传递和值传递

    关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...

  2. Java Object 引用传递和值传递

    Java Object 引用传递和值传递 @author ixenos Java没有引用传递: 除了在将参数传递给方法(或函数)的时候是"值传递",传递对象引用的副本,在任何用&q ...

  3. (转载)理解Java中的引用传递和值传递

      关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天 ...

  4. Java中的引用传递和值传递

    Java中的引用传递和值传递 关于Java的引用传递和值传递,在听了老师讲解后,还是没有弄清楚是怎么一回事,于是查了资料,所以在这里与大家分享,有不对的地方,欢迎大家留言. java中是没有指针的,j ...

  5. Java中没有引用传递只有值传递(在函数中)

    ◆传参的问题 引用类型(在函数调用中)的传参问题,是一个相当扯的问题.有些书上说是传值,有些书上说是传引用.搞得Java程序员都快成神经分裂了.所以,我们最后来谈一下“引用类型参数传递”的问题. 如下 ...

  6. Java千百问_05面向对象(011)_引用传递和值传递有什么差别

    点击进入_很多其它_Java千百问 1.什么是值传递 值传递,是将内存空间中某个存储单元中存放的值,传送给还有一个存储单元.(java中的存储单元并不是物理内存的地址,但具有相关性) 比如: //定义 ...

  7. java引用传递和值传递

    关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...

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

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

  9. effective c++:引用传递与值传递,成员函数与非成员函数

    以pass-by-reference-to-const 替换pass-by-value 考虑以下class继承体系 class Person { public: Person(); // parame ...

随机推荐

  1. ajax 原生态和jquery封装区别

    一.原生态 var xmlHttp = false; try{ if( xmlHttp && xmlHttp.readyState != 0 ){ xmlHttp.abort(); } ...

  2. Nginx负载均衡和反向代理

    1:反向代理 代理就是中介,那有反向代理就有正向代理,两者的区别是什么嘞? 正向代理隐藏真实客户端,服务端不知道实际发起请求的客户端.,proxy和client同属一个LAN,对server透明: 反 ...

  3. Java并发之AQS详解

    一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)! 类如其名,抽象的队列式的同步器,AQ ...

  4. sniffer 简介

    http://www.doc88.com/p-095375416629.html 介绍sniffer的工作原理及简单介绍.

  5. python_pycharm下拉前置标示

    在pycharm中是自动补全的变量的类别p:parameter 参数m:method方法c:class 类v:variable 变量f:function 函数 从定义的角度上看,我们知道函数(func ...

  6. mint-ui之picker爬坑记

    picker的数据来源为动态获取时,数据无法正常渲染!因为方法不对,所以坑大了!深刻地体会到'业不精,我之过',谨以此文,深刻地记录一下踩坑及爬坑的整个过程,以便日后不再入坑,也给后来者提供一下参考 ...

  7. Hibernate中的多表查询及抓取策略

    1.Hibernate中的多表查询 1.1SQL中的多表查询 [交叉连接] select * from A,B; [内连接] 显示内连接:inner join(inner 可以省略) Select * ...

  8. WebJars

    WebJarsWebJars是一个很神奇的东西,可以让大家以jar包的形式来使用前端的各种框架.组件. 什么是WebJars 什么是WebJars?WebJars是将客户端(浏览器)资源(JavaSc ...

  9. PHP使用文件排它锁,应对小型并发

    总所知周,并发容易造成数据的重复处理,我的一个项目给游戏客户端提供了接口,游戏用户相对较多,如果使用数据库排它锁消耗的资源较高,因而使用了文件的排它锁来应对并发. 思路是打开一个文件并取得文件的独占锁 ...

  10. 玩转spring mvc(四)---在spring MVC中整合JPA

    关于在Spring MVC中整合JPA是在我的上一篇关于spring mvc基本配置基础上进行的,所以大家先参考一下我的上一篇文章:http://blog.csdn.net/u012116457/ar ...