西唐生物:Java常见笔试面试题目解析(二): Java中的原生数据类型和引用类型的参数传递 - 学海拾贝 - JavaEye技术网站

来源:百度文库 编辑:九乡新闻网 时间:2024/04/25 13:23:29

  1. public class Point  
  2. {  
  3.     private int x;  
  4.     private int y;  
  5.   
  6.     public Point(int x,int y)  
  7.     {  
  8.         this.x = x;  
  9.         this.y = y;  
  10.     }  
  11.     public int getX()  
  12.     {  
  13.         return x;  
  14.     }  
  15.     public void setX(int x)  
  16.     {  
  17.         this.x = x;  
  18.     }  
  19.     public int getY()  
  20.     {  
  21.         return y;  
  22.     }  
  23.     public void setY(int y)  
  24.     {  
  25.         this.y = y;  
  26.     }  
  27. }  
  28.   
  29.   
  30. public class ParameterTest  
  31. {  
  32.     public void changeInt(int a)  
  33.     {  
  34.         a = 3;  
  35.     }  
  36.     public void changePoint(Point point)  
  37.     {  
  38.         point.setX(5);  
  39.         point.setY(6);  
  40.     }  
  41.     public void changeString(String str)  
  42.     {  
  43.         str = "abc";  
  44.         System.out.println(str);  
  45.     }  
  46.     public static void main(String[] args)  
  47.     {  
  48.         int a = 1;// 语句(1)  
  49.         ParameterTest pt = new ParameterTest();// 语句(2)  
  50.         pt.changeInt(a);// 语句(3)  
  51.         System.out.println(a);// 语句(4)  
  52.         Point point = new Point(1, 2);// 语句(5)  
  53.         pt.changePoint(point);// 语句(6)  
  54.         System.out.println(point.getX());// 语句(7)  
  55.         System.out.println(point.getY());// 语句(8)  
  56.         String str = "xyz";// 语句(9)  
  57.         pt.changeString(str);// 语句(10)  
  58.         System.out.println(str);// 语句(11)  
  59.           
  60.         System.out.println(pt);  
  61.     }  
  62. }  

 

 

 

问题1:当执行完语句(4)后,打印的结果是什么?为什么?
解答:当执行完语句(4)后,打印的结果是1。分析:首先调用定义 int a = 1;然后调用对象的changeInt(int a)方法,流程转到changeInt方法里面去,把a的值赋给了方法changeInt的形式参数,changeInt方法里面参数a的值为1,然后执行性方法体里的语句a = 3,即是将changeInt方法里面参数a的值由1改为3;注意:这个时候对方法changeInt方法里面参数a的值改变并没有影响到main方法里面的a的值,为什么?对于原生数据类型来说,它仅仅是把 main方法里面的a的值传过去,传值完后,两者之间没有任何的关系,你在changeInt方法里面对参数a的改变,对外面main方法的a没有任何的影响。因为我只是把值拷贝一份给你,拷贝完以后,你是你的我是我的,两者之间没有任何关系。因此,当执行完语句(4)后,打印结果是1。

总结:对八种原生数据类型来说,它们传递的时候传递的是它们的值(value),是值的拷贝,拷贝过去过后,你是你,我是我,两者之间无任何关系。所以,方法里面对拷贝过来的值的改变,对被拷贝的原生数据类型没有任何的影响。

问题2:当执行完语句(7)(8)后,打印的结果是什么?为什么?
解答:当执行完语句(7)(8)后,打印的结果分别是5,6。分析:语句(5)Point point = new Point(1,2),首先生成一个横坐标是1,纵坐标是2的Point对象,因为有关键字new...,point是指向刚生成的这个对象的引用,即是刚生成的对象的内存地址,接着执行语句(6),调用changePoint方法,它会把引用point传过去赋值给changePoint(Point point)里面的point.注意:传的是引用,即是对象的内存地址,接着把对象的x改为5,y改为6,这时对象的横纵坐标发生了改变,分别变为5和 6。也就是说,在changePoint方法里面,对point所指向的对象的x和y的改变会反应到你外面生成的这个对象,也就是1被改成了5,2被改成了6。这个对象为什么会改变?这就涉及到 java对引用类型的传递方式上,首先语句(5)表示在内存的堆里面生成了一个Point类型的对象,point这个引用它指向堆里面生成的Point类型的对象,这个对象里x坐标是1,y坐标是2。接着去调用changePoint方法,在调用这个方法的时候,它会把point这个引用传给 changePoint方法里面的point参数。在java里面,引用在java里面是对象在内存堆里面的地址,它是把对象的地址传递到了 changePoint方法里面去了。地址本身也是一个int类型的值,它把地址通过参数的形式传递过去。举例:比如说new Point(1,2)这个对象在内存堆中的地址是1234,那么调用changePoint方法,它传给changePoint(Point point)里面的point的地址也是1234,changePoint方法外面的引用指向了堆里面生成的Point类型的对象,那么对 changePoint方法里面的参数引用也指向同一个堆里面生成的Point类型的对象,java里面只要有两个引用它们的地址是一样的必然指向同一个对象。所以说当changePoint方法调用的时候,方法里面的引用和方法外面的引用它们指向的是同一个对象,究其原因它们是内存地址的传递,两个引用的内存地址是一样的必然指向同一个对象。通过执行changePoint方法里面的语句,把这个引用指向的对象的x改为5,y改为6。然后方法结束,结束之后,我打印changePoint方法外面这个引用它所指向对象的x坐标和y坐标,因为这两个引用指向的是同一个对象,所以结果是5和6。

问题3:当执行完语句(11)后,打印的结果是什么?为什么?
解答:当执行完语句(11)后,打印的结果是xyz。分析:语句(9) String str = "xyz";表示str这个引用指向常量"xyz"(在String Pool里面),当执行语句(10)的changeString(String str)方法时,将全局的str引用传递给changeString方法里面的str,这时会导致全局的str引用和changeString方法里面的引用会指向同一个对象"xyz",所以当完成参数传递还没有执行方法里面的语句体的时候,它们的引用是指向同一个对象"xyz"的,接着执行方法体里面的语句,这时会在String Pool里面生成一个"abc"的对象,同时将方法体里面的str指向String Pool里面的"abc"对象。一个引用在某一时刻始终只能指向一个对象,changString方法外面的str始终是指向"xyz"对象的。所以输出的时候始终是"xyz"。

总结: 在java里面,对方法的参数传递,不管是原生数据类型还是引用类型,一律是传值:pass by value。对原生数据类型来说,传递的值就是它被赋予的那个值,比如说 int a = 3 就把3这个值传到方法里面去;引用类型来说,引用本身是一个地址,是一个int类型的内存地址值,所以说它把这个值传递到方法里面去传递的也是值。