良许Linux教程网 干货合集 探究java关于值传递还是引用传递的问题

探究java关于值传递还是引用传递的问题

值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量. 引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。 一般认为,java内的基础类型数据传递都是值传递. java中实例对象的传递是引用传递

探究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具体的执行过程为:

  1. x被初始化为price值的一个拷贝,即5
  2. x乘以2后等于10。但是price没有变化,依然是5
  3. doubleValue执行完后,参数变量不再使用
img

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的内容改变了。

具体执行过程为:

  1. s被赋予stu值的拷贝,这里是一个对象的引用
  2. raiseScore方法应用于这个应用。s和stu指向同一对象,该对象的分数增加了10
  3. raiseScore方法结束后,s不再使用,stu指向的那个对象分数增加了10
img

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调用的过程:

  1. 将对象a,b的拷贝分别赋值给x,y,此时a和x指向同一对象,b和y指向同一对象
  2. swap方法体完成x,y的的交换,此时a,b并没有变化
  3. 方法执行完成,x和y不再使用,a依旧指向new Student(0),b指向new Student(100)

首先,创建两个对象:

img

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

img

接着,交换x,y的值:

img

swap执行完成,x,y不再使用,回到创建时状态。

从这个过程中可以看出,Java对对象采用的不是引用调用,实际上,对象引用进行的是值传递。

总结一下java中方法参数的使用情况:

  • 一个方法不能修改一个基本数据类型的参数(即数值型和布尔型)
  • 一个方法可以改变一个对象参数的状态
  • 一个方法不能让对象参数引用一个新的对象

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

img
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部