• 0

  • 0

Java值传递还是引用传递?

6天前

从我实习面试开始就有在面试中遇到过这个问题:Java是值传递还是引用传递?

当时的我只会背背面试题,但是网上的答案有些还是错的,导致我决心写这一篇文章。

虽然网上已经有很多文章珠玉在前,但是我还是想写一篇我自己的文章,如果写的不好,请见谅

文章开始之前我们还是来解答Java是值传递还是引用传递?这个问题吧!答案自然是:Java是值传递

给定结论后我们再来解释一下什么叫 值传递&引用传递
  • 值传递:值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

  • 引用传递:引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

以下图片来自百度百科

上代码证明:

/**
 * 证明java值传递demo
 *
 * @author miao
 */
public class PassValueDemo {   public static void main(String[] args) {   int a = 1;  String str = "1";  User user = new User("阿花", 6);   System.out.println("调用方法前a为:" + a);  System.out.println("调用方法前str为:" + str);  System.out.println("调用方法前user为:" + user);   System.out.println("------------------------------------------");  convert(a, str, user);  System.out.println("------------------------------------------");   System.out.println("调用方法后a为:" + a);  System.out.println("调用方法后str为:" + str);  System.out.println("调用方法后user为:" + user);  }   private static void convert(int a, String str, User user) {  a = 2;  str = "2";  user.setAge(9);  user.setUsername("大壮");   System.out.println("调用方法中a为:" + a);  System.out.println("调用方法中str为:" + str);  System.out.println("调用方法中user为:" + user);  }  }  /**  * @author miao  */ class User {   public String username;   public int age;   public User(String username, int age) {  this.username = username;  this.age = age;  }   public String getUsername() {  return username;  }   public void setUsername(String username) {  this.username = username;  }   public int getAge() {  return age;  }   public void setAge(int age) {  this.age = age;  }   @Override  public String toString() {  return "User{" +  "username='" + username + '\'' +  ", age=" + age +  '}';  } } 复制代码

程序的执行结果:

调用方法前a为:1
调用方法前str为:1
调用方法前user为:User{username='阿花', age=6}
------------------------------------------
调用方法中a为:2
调用方法中str为:2 调用方法中user为:User{username='大壮', age=9} ------------------------------------------ 调用方法后a为:1 调用方法后str为:1 调用方法后user为:User{username='大壮', age=9} 复制代码

我们可以看到,身为基本类型的int和被final修饰的String并没有改变,但是引用类型User改变了,所以,网上就有人得出了结论:java针对基本类型是值传递,对于引用类型是引用传递但是!!!!这是错误的结论,不相信的话,我在上面的代码中加一行代码,就知道为什么这个是错的结论了

在convert()方法中str = "2";下面增加一行user = new User("小美", 18),让我们看看这样的结果是什么?

程序的执行结果:

调用方法前a为:1
调用方法前str为:1
调用方法前user为:User{username='阿花', age=6}
------------------------------------------
调用方法中a为:2
调用方法中str为:2 调用方法中user为:User{username='大壮', age=9} ------------------------------------------ 调用方法后a为:1 调用方法后str为:1 调用方法后user为:User{username='阿花', age=6} 复制代码
从上述结果可以看出,当我们在 convert 方法中添加 user = new User("小美", 18)之后,“引用传递”就突然变值传递了?为什么?

这是因为,在 Java 语言中本质上只有值传递,也就说 Java 的传参只会传递它的副本,并不会传递参数本身。

即传入convert()时的user为 User user的副本,指向同一个new User("阿花", 6)的堆地址,

当执行user = new User("小美", 18)时,指向的堆内存改变了,所以再进行任何操作都跟之前的堆地址没关系了,即证实了,传递的是一个副本。

未执行user = new User("小美", 18)之前

执行user = new User("小美", 18)之后

总结:通过本文的内容,我们可以得出:在 Java 语言中只有值传递,方法传参时只会传递副本信息而非原内容。我们还知道了基础数据类型会直接生成到栈上,而对象或数组则会在栈和堆上都生成信息,并将栈上生成的引用,直接指向堆中生成的数据

免责声明:文章版权归原作者所有,其内容与观点不代表Unitimes立场,亦不构成任何投资意见或建议。

java

0

相关文章推荐

未登录头像

暂无评论