Java值传递还是引用传递?
回顾:
在程序设计语言中,将参数传递分为按值调用和按引用调用。按值调用:表示方法接收的是调用者提供的值。而按引用调用表示方法接收的是调用者提供的变量地址。
一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。
Java总是采用按值调用。方法得到的是所有参数值的一个拷贝,特别的,方法不能修改传递给它的任何参数变量的内容。
方法参数共有两种类型:
- 基本数据类型
- 对象引用
1. 基本数据类型为参数
查看一下的代码:
public class ParamTest {
public static void main(String[] args) {
int price = 5;
doubleValue(price);
System.out.print(price);
}
public static void doubleValue(int x) {
x = 2 * x;
}
}
【输出结果】: 5
可以看到,这个方法执行之后,price的值并没有变化。接下来,看一下doubleValue具体的执行过程为:
- x被初始化为price值的一个拷贝,即5
- x乘以2后等于10。但是price没有变化,依然是5
- doubleValue执行完后,参数变量不再使用

2. 对象引用为参数
从上面的例子我们已经知道一个方法不能修改一个基本数据类型的参数。而对象引用作为参数就不同了。看下面的例子:
class Student {
private float score;
public Student(float score) {
this.score = score;
}
public void setScore(float score) {
this.score = score;
}
public float getScore() {
return score;
}
}
public class ParamTest {
public static void main(String[] args) {
Student stu = new Student(80);
raiseScore(stu);
System.out.print(stu.getScore());
}
public static void raiseScore(Student s) {
s.setScore(s.getScore() + 10);
}
}
【运行结果】:
90.0
可以看出,Student实例s的内容改变了。
具体执行过程为:
- s被赋予stu值的拷贝,这里是一个对象的引用
- raiseScore方法应用于这个应用。s和stu指向同一对象,该对象的分数增加了10
- raiseScore方法结束后,s不再使用,stu指向的那个对象分数增加了10

3. 对对象是值调用还是引用传递?
首先编写一个交换两个学生的方法:
public static void swap(Student x, Student y) {
Student temp = x;
x = y;
y = temp;
}
如果java对对象是采用的是引用传递,那个这个方法是可以的。那么x,y对象的分数是交换的。看下面的例子:
class Student {
private float score;
public Student(float score) {
this.score = score;
}
public void setScore(float score) {
this.score = score;
}
public float getScore() {
return score;
}
}
public class ParamTest {
public static void main(String[] args) {
Student a = new Student(0);
Student b = new Student(100);
System.out.println("交换前:");
System.out.println("a的分数:" + a.getScore() + "--- b的分数:" + b.getScore());
swap(a, b);
System.out.println("交换后:");
System.out.println("a的分数:" + a.getScore() + "--- b的分数:" + b.getScore());
}
public static void swap(Student x, Student y) {
Student temp = x;
x = y;
y = temp;
}
}
【运行结果】:
交换前:
a的分数:0.0--- b的分数:100.0
交换后:
a的分数:0.0--- b的分数:100.0
可以看出,两者并没有实现交换。说明引用传递的说法是不正确的。接下来一步一步看看swap调用的过程:
- 将对象a,b的拷贝分别赋值给x,y,此时a和x指向同一对象,b和y指向同一对象
- swap方法体完成x,y的的交换,此时a,b并没有变化
- 方法执行完成,x和y不再使用,a依旧指向new Student(0),b指向new Student(100)
首先,创建两个对象:

然后,进入方法体,将对象a,b的拷贝分别赋值给x,y:

接着,交换x,y的值:

swap执行完成,x,y不再使用,回到创建时状态。
从这个过程中可以看出,Java对对象采用的不是引用调用,实际上,对象引用进行的是值传递。
总结一下java中方法参数的使用情况:
- 一个方法不能修改一个基本数据类型的参数(即数值型和布尔型)
- 一个方法可以改变一个对象参数的状态
- 一个方法不能让对象参数引用一个新的对象
Java值传递还是引用传递?的更多相关文章
- Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义
一.Java中什么叫做引用类型变量?引用:就是按内存地址查询 比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...
- java中值传递和引用传递
最近工作中使用到了值传递和引用传递,但是有点懵,现在看了下面的文章后清晰多了.一下是文章(网摘) 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...
- Java中的值传递和引用传递
这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ...
- java的值传递和引用传递
昨天博主在对于值传递和引用传递这里栽了一个大坑啊,导致一下午时间都浪费在这里,我们先说下值传递和引用传递java官方解释: 值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对 ...
- java中方法的参数传递机制(值传递还是引用传递)
看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值传递参 ...
- java 对象传递 是 值传递 还是 引用传递?
这个问题说实话我感觉没有太大的意义. 按第一印象和c++的一些思想去理解的话对象传递是引用传递,因为传递过去的对象的值能被改变. 但是又有很多人,不知道从哪里扣出来一句,java中只有值传递,没有引用 ...
- java参数传递时到底是值传递还是引用传递
java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...
- Java面向对象-方法的值传递和引用传递
Java面向对象-方法的值传递和引用传递 0 发布时间:『 2016-08-21 14:21』 博客类别:Java核心基础 阅读(197) 评论(0) Java面向对象-方法的值传递和引用传递 方 ...
- Does Java pass by reference or pass by value?(Java是值传递还是引用传递) - 总结
这个话题一直是Java程序员的一个热议话题,争论不断,但是不论是你百度搜也好还是去看官方的文档中所标明的也好,得到的都只有一个结论:Java只有值传递. 在这里就不贴代码细致解释了,让我们来看看一些论 ...
- Java值传递和引用传递
Java总是在讨论是传递还是引用传递,Java没有像C语言那样拥有指针,在看到引用传递和值传递很多的解释之后,更相信引用传递和值传递归根到底都是值传递,只不过引用传递的时候看上去很高大上,其实是把变量 ...
随机推荐
- thinkphp 模板里嵌入 php代码
<php> echo 'nihao';</php><?phpecho 'gge';?> Php代码可以和标签在模板文件中混合使用,可以在模板文件里面书写任意的PHP ...
- Jmeter - 分布式部署负载机
1. 原理图: 2.具体操作 ① 负载机 安装JDK.Jmeter[版本与Controller 调度机一致] ② 配置环境变量 ③ 负载机自定义端口号 a.进入Jmeter的bin目录,找到Jmete ...
- 【工具】SwitchHost的使用
一.问题: 更改Host后,再次启用或者关闭启动Host,Host被恢复原状.原因是修改Host的顺序顺序有问题. 二.解决步骤: 修改Host之前,先点击右下角,关闭所有Host(白色的部分在下面表 ...
- Linux网络配置:设置IP地址、网关DNS、主机名
查看网络信息 1.ifconfig eth0 2.ifconfig -a 3.ip add 设置主机名需改配置文件: /etc/hosts /etc/sysconfig/network vim /et ...
- 码云平台, Git提交需要输入用户名/密码, 怎么办
这是因为, 检出代码的时候, 使用了http的方式: 那么, 改为ssh的地址就行了
- Collections工具类的使用
创建实体类 public class News implements Comparable { private int id; //新闻编号 private String title; //新闻标题 ...
- Redis、MongoDB及Memcached的区别 Redis(内存数据库)
Redis.MongoDB及Memcached的区别 Redis(内存数据库) 是一个key-value存储系统(布式内缓存,高性能的key-value数据库).和Memcached类似,它支持存储的 ...
- Python高级教程-生成器
生成器(Generator) 通过列表生成式,可以直接创建一个列表.但是,受内存限制,列表的容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几 ...
- 对ASIHTTPRequest的封装
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/quanqinayng/article/details/37659751 .h文件 // // Ht ...
- 数据库、Java与Hibernate数据类型对照
数据类型对照表: 标准SQL数据类型 Java数据类型 Hibernate数据类型 TINYINT byte.java.lang.Byte byte SMALLINT short.java.lang. ...