萍聚社区-德国热线-德国实用信息网

 找回密码
 注册

微信登录

微信扫一扫,快速登录

萍聚头条

查看: 604|回复: 0

1-1-4-1-3 Java中的参数传递之个人见解[引用和传值]

[复制链接]
发表于 2003-2-6 16:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册 微信登录

x

  1. 发信人: virtualmfc (苦苦追求永远追求不到的东西), 信区: Java      
  2. 标  题: Java中的参数传递之个人见解[引用和传值]
  3. 发信站: BBS 水木清华站 (Thu Aug 22 11:27:05 2002), 站内信件

  4. 大家对C++中的引用和传值函数调用应该不陌生。然而,初次接触Java后,被这个问题着实
  5. 迷惑了一阵子。在看了IBM的Java园地中相关的文章后,有些想法,大胆讲出来,希望能听
  6. 到不同的声音。
  7. 在C++中,有三种参数传递方法,一种是传值、一种是传址、一种是引用。下面分别列出这
  8. 三种的情形:
  9. //传值调用swap
  10. void swap(int a,int b)
  11. {
  12.         int tmp = a;
  13.         a = b;
  14.         b = a;
  15. }
  16. void swap2(int * a,int *b)
  17. {
  18.         int tmp = *a;
  19.         *a = *b;
  20.         *b = tmp;
  21. }
  22. void swap3(int &a,int &b)
  23. {
  24.         int tmp = a;
  25.         a = b;
  26.         b = tmp;
  27. }
  28. int main(int argc,char **argv)
  29. {
  30.         int a = 3;
  31.         int b = 5;
  32.         swap(a,b);
  33.         swap2(&a,&b);
  34.         swap3(a,b);
  35. }
  36. 内部机制用图形表示比较直观一点:(变量地址是假设的,依情况不同而变化)
  37. /*****************main中**********************\
  38. 变量名       a                                              b
  39. 值             3                                              5
  40. 内存地址    0x7200                                   0x71FE
  41. ****************函数swap中********************
  42. 变量名       a                                              b
  43. 值             3                                              5
  44. 内存地址    0x9200                                   0x91FE
  45. *****************执行完成后**********************
  46. 变量名       a                                              b
  47. 值             5                                              3
  48. 内存地址    0x9200                                   0x91FE
  49. \********************************************/
  50. 可以看出,由于C++中的传值调用问题,所以虽然swap(int,int)函数中的局部变量a,b的值
  51. 改变了,但因为此a,b与main中的
  52. 彼a,b是内存中的不同存储单元,所以对main中的变量毫无影响。swap(int,int)不能完成
  53. 交换的任务。
  54. /*****************main中**********************\
  55. 变量名       a                                              b
  56. 值             3                                              5
  57. 内存地址    0x7200                                   0x71FE
  58. ****************函数swap2中********************
  59. 变量名       a                                              b
  60. 值             0x7200                                   0x71FE
  61. 内存地址    0x9200                                   0x91FE
  62. *****************执行完成后**********************
  63. 变量名       a                                              b
  64. 值             5                                              3
  65. 内存地址    0x9200                                   0x91FE
  66. \********************************************/
  67. 同样分析,由于C++传递参数时始终是传值调用(下面我们将看到,引用也不例外,只是稍
  68. 微有点特殊 ),所以,main()函
  69. 数中的a和b分别布局在内存中的0x7200和0x71FE处,调用swap2(int *,int *)后,函数sw
  70. ap2(int *,int *)中的局部指针变量a,b的位址是0x9200和0x91FE,然而,其值是0x7200和
  71. 0x71FE,分别指向main函数中的a,b。
  72. 所以,经过调用后,main函数中的a,b会交换值。函数swap2(int *,int *)可以正常工作。

  73. 下面要特别注意,这正是Java和C++不同的地方,也是特别容易混淆的地方。
  74. /*****************main中**********************\
  75. 变量名       a                                              b
  76. 值             3                                              5
  77. 内存地址    0x7200                                   0x71FE
  78. ****************函数swap3中********************
  79. 变量名       a                                              b
  80. 值             0x7200                                   0x71FE
  81. 内存地址    0x9200                                   0x91FE
  82. *****************执行完成后**********************
  83. 变量名       a                                              b
  84. 值             5                                              3
  85. 内存地址    0x9200                                   0x91FE
  86. \********************************************/
  87. 引用的机制在C++中我不是很清楚,但有一点,它的工作机制非常象指针,只是不用进行解
  88. 引用操作。而且,引用不能赋值,只能进行初始化。(请注意这句话)。所以,我们常常
  89. 叫它别名。
  90. void swap3(int &a,int &b)
  91. {
  92.         int tmp = a; // a是主函数main中的局部变量a的引用,或者说,指向main中的植勘淞
  93. a
  94.         a = b;  //b是主函数main中的局部变量b的引用,或者说,指向main中的局部变縝
  95.         b = tmp;//以上由于引用的特性,所以a=b时,不是说a引用b,而是b的值赋给a,b=tmp是
  96. 同样的。
  97.         
  98.         //由于这里的a,b和main中的a,b是同一个东西,所以也完成了交换值的任务。
  99. }
  100. 而java中除了此引用外,同样也是传值,但与其说Java中的引用叫引用,不如称之为指针
  101. 。使用下面的java示例可以说明问题
  102. class Swap
  103. {
  104.   public static void main(String args[])
  105.   {
  106.     Integer a, b;
  107.     a = new Integer(10);
  108.     b = new Integer(50);
  109.     System.out.println("before swap...");
  110.     System.out.println("a is " + a);
  111.     System.out.println("b is " + b);
  112.     swap(a, b);
  113.     System.out.println("after swap...");
  114.     System.out.println("a is " + a);
  115.     System.out.println("b is " + b);
  116.   }
  117.   public static void swap(Integer a, Integer b)
  118.   {
  119.     Integer temp = a; //a,b是main方法中的a,b的指针
  120.     a = b;  //a指向b
  121.     b = temp;//b指向a
  122.    
  123.     //因为只有swap方法中的局部参数变量a,b的指针指向变化,所以对main方法中的数值
  124. 毫无影响。
  125.   }
  126. }
  127. 再举一个更能说明问题的例子,来说明java中的对象引用不同C++一样,只能初始化,而且
  128. 可以任意指向的问题(所以我认为更适合称之为“自解引用指针”)。
  129. import java.awt.Point;
  130. public class Assign {
  131.                 int a = 1;
  132.                 int b = 2;
  133.                 Point x = new Point(0,0);
  134.                 Point y = new Point(1,1);      
  135.                
  136.         public static void main(String[] args) {
  137.                 System.out.println("a is " + a);
  138.                 System.out.println("b is " + b);
  139.                 System.out.println("x is " + x);
  140.                 System.out.println("y is " + y);
  141.                
  142.                 System.out.println("Performing assignment and  " + "setLocation...");
  143.                
  144.                 a = b; // a == 2
  145.                 a ++; // a == 3
  146.                 x = y; // x指向y
  147.                 x.setLocation(5,5); //x指向的point的值为[5,5],因为x指向y,所以Point y的值也为
  148. [5,5]
  149.                 //原来x指向的point(0,0)已经丢失了,象C++中的内存泄露一样,不过挥玫P模琂ava
  150. 的垃圾收
  151.                 //集器会帮忙料理的,不用担心。
  152.                
  153.                 System.out.println("a is " + a);
  154.                 System.out.println("b is " + b);
  155.                 System.out.println("x is " + x);  // x == [5,5]
  156.                 System.out.println("y is " + y); // y == [5,5]
  157.         }
  158. }
  159. 好了,现在大家应该清楚Java中的参数传递和所谓的“引用传递”了吧。写了这么多,还
  160. 是这么一句话,我个人认为,Java中称对象传递的是引用并不恰当。改成“自解引用指针
  161. ”对C/C++程序员可能更好理解。大家认为呢?

复制代码
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
您需要登录后才可以回帖 登录 | 注册 微信登录

本版积分规则

手机版|Archiver|AGB|Impressum|Datenschutzerklärung|萍聚社区-德国热线-德国实用信息网 |网站地图

GMT+2, 2024-5-21 18:10 , Processed in 0.059358 second(s), 19 queries , MemCached On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表