Java是值传递还是引用传递?

开门见山:Java中只有值传递!

一、错误认知

基本类型是值传递,对象类型是引用传递。

二、形参与实参

1. 形式参数

方法中声明的用于接收的参数。

2. 实际参数

调用方法时传递的参数。

三、值传递与引用传递

1. 值传递(创建副本)

指将实参copy一份,赋给形参。修改形参时,不改变原本实参的值。

2. 引用传递(不创建副本)

指将地址直接传给形参。修改形参时,改变原本实参的值。

四、三段代码解释

1. 基本变量值传递
public static void main(String[] args) {

   int i = 10;
   pass(i );//在pass方法中输出一次
   System.out.println(i);//i=10,pass方法结束后输出一次
}

public void pass(int j) {
   j = 20;
   System.out.println(j);//j=20
}

从代码中可以看到,i与j结果不同,是因为i传给j时,创建了一个副本给j,修改j时,跟i没关系。

2. User对象值传递
public static void main(String[] args) {

   User a= new User();
   a.setName("小龙女");
   pass(a);
   System.out.println(a);//第二次输出,user.name = '杨过'
}

public void pass(User user) {
   user.setName("杨过");
   System.out.println(user);//第一次输出,user.name = '杨过'
}
  • 以上代码有人可能就有疑问了,不是说值传递吗,为什么形参地址的变量的“值”改变了,实参地址的变量的“值”也会改变呢?
  • 注意,我这里说的是形参地址——的变量——的值改变。
  • 回顾一下值传递的定义:
    指将实参copy一份,赋给形参。修改形参时,不改变原本实参的值。
    而我们这里改变的不是形参,而是形参所指的对象的值。
  • 所以我们认为,pass(a),其实传的是地址(这个地址也是值传递)。
3. 如果还是有疑问,请看下面
public static void main(String[] args) {

   User a= new User();
   a.setName("小龙女");
   pass(a);
   System.out.println(a);//第二次输出,user.name = '小龙女'
}

public void pass(User user) {
   user = new user();
   user.setName("杨过");
   System.out.println(user);//第一次输出,user.name = '杨过'
}
  • 咦,为什么只是多了一行user = new user();就截然不同了呢?
  • 因为这里,在值传递时,pass方法中new了一个新的对象,这个对象的地址与原本实参不一样。并把新的地址给了user。
  • 如果此时是引用传递,那么原本对象a的地址是不是也该变为新对象的地址。但是实际没有。因此证明形式参数user也是一个创建了副本的。而创建副本的就是值传递。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容