java中参数传递

总之一句话:java中只有副本传递,对于值,拷贝值,对于引用,拷贝引用(对于数组,数组名传递的都是引用)。

  1. /**
  2. * java中只有副本传递,对于值,拷贝值,对于引用,拷贝引用(对于数组,数组名传递的都是引用)。
  3. * @author sargeles
  4. */
  5. public class About_Onlyvaluetransmit {
  6. /**
  7. * 测试一组:基本类型传递是按值传递,意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。
  8. * String因为两个原因表现出基本类型的特征: 一个是String实际上操作的是char[],可以理解为String是char[]的包装类
  9. * 二是给String变量重新赋值后,实际上没有改变这个变量的值,而是重新new了一个String对象,这里涉及到String不可变这一特性。
  10. */
  11. static void ceshi1() {
  12. int i = 1;
  13. String s = new String("I‘ll change you!");
  14. A a = new A();
  15. a.change(i, s);
  16. a.show();
  17. System.out.println("被传入并修改的i=" + i);
  18. System.out.println("被传入并修改的s=" + s);
  19. }
  20. /**
  21. * 测试二组:引用类型传递是副本传递,意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。
  22. * 但需要注意到的是,ceshi2里定义的b,会被直接传递给a,作为a的属性,而不是复制给a,
  23. * 也就是说对象b并不会被拷贝,对change()传递参数后,A.b与b指向同一个对象。 也是遵循‘引用传递’这四个字。
  24. */
  25. static void ceshi2() {
  26. int[] intarray = { 0, 1, 2 };
  27. String[] strarray = { "aaa", "bbb", "ccc" };
  28. A a = new A();
  29. B b = new B(1);
  30. a.change(intarray, strarray, b);
  31. a.show();
  32. System.out.println("被传入的i=" + intarray[1]);
  33. System.out.println("被传入的s=" + strarray[1]);
  34. System.out.println("被传入的b.index=" + b.index);
  35. System.out.println("被传入的b的hash值=" + b.hashCode());
  36. }
  37. /**
  38. * 为了进一步证实ceshi2中的引用传递,这次我们测试的是数组的引用,而不是对象的引用。
  39. */
  40. static void ceshi3() {
  41. int[] intarray = { 0, 1, 2 };
  42. A a = new A();
  43. a.change(intarray);
  44. a.show();
  45. System.out.println("被传入的intarray=" + intarray);
  46. System.out.println("被传入的intarray[0]=" + intarray[0]);
  47. }
  48. public static void main(String[] args) {
  49. ceshi1();
  50. //ceshi2();
  51. // ceshi3();
  52. }
  53. }
  54. class A {
  55. int i = 0;
  56. int[] ii = { 0, 1, 2 };
  57. String s = "I‘m not changed!";
  58. B b = new B(0);
  59. /**
  60. * ceshi1专用
  61. */
  62. void change(int i, String s) {
  63. this.i = i;
  64. i++;
  65. this.s = s;
  66. s = "I‘ll change you!But I have been changed too!";
  67. }
  68. /**
  69. * ceshi2专用
  70. */
  71. void change(int[] i, String[] s, B b) {
  72. this.i = i[1];
  73. i[1]++;
  74. this.s = s[1];
  75. s[1] = "I‘ll change you!But I have been changed too!";
  76. this.b = b;
  77. // 下面的语句改为 this.b.index++; 效果不变。
  78. b.index++;
  79. }
  80. /**
  81. * ceshi3专用
  82. */
  83. public void change(int[] intarray) {
  84. this.ii = intarray;
  85. intarray[0]++;
  86. }
  87. public void show() {
  88. if (i != 0)
  89. System.out.println("A的对象a中i=" + i);
  90. if (ii[0] != 0) {
  91. System.out.println("A的对象a中ii=" + ii);
  92. System.out.println("A的对象a中ii[0]=" + ii[0]);
  93. }
  94. if (!s.equals("I‘m not changed!"))
  95. System.out.println("A的对象a中s=" + s);
  96. System.out.println();
  97. try {
  98. if (b.index != 0) {
  99. System.out.println("A的对象a中b.index=" + b.index);
  100. System.out.println("A的对象a中b的hash值=" + b.hashCode());
  101. System.out.println();
  102. }
  103. } catch (java.lang.NullPointerException e) {
  104. System.out.println("未得到B对象!");
  105. }
  106. }
  107. }
  108. class B {
  109. int index = 0;
  110. public B(int i) {
  111. index = i;
  112. }
  113. }

ceshi1的输出:

  1. A的对象a中i=1
  2. A的对象a中s=I‘ll change you!
  3. 被传入并修改的i=1
  4. 被传入并修改的s=I‘ll change you!

ceshi2的输出:

  1. A的对象a中i=1
  2. A的对象a中s=bbb
  3. A的对象a中b.index=2
  4. A的对象a中b的hash值=2046587545
  5. 被传入的i=2
  6. 被传入的s=I‘ll change you!But I have been changed too!
  7. 被传入的b.index=2
  8. 被传入的b的hash值=2046587545

ceshi3的输出:

  1. A的对象a中ii=[[email protected]
  2. A的对象a中ii[0]=1
  3. 被传入的intarray=[[email protected]
  4. 被传入的intarray[0]=1

关于引用传递,如果还看不懂,不妨继续看下去。

在ceshi2中,执行第92行语句的之前,两个b是不同的id,一个是25,一个是21,说明是不同的实例。

执行后,可以看到两者变为同一id,说明引用被拷贝并传递了,现在已经没有引用指向B的id为25的实例。

在执行94行语句的时候,同时改变了两个地方,说明this.b和b只是同一个实例对象的不同引用而已。它们内部的属性值是一样的。

来自为知笔记(Wiz)

时间: 2024-08-25 06:25:05

java中参数传递的相关文章

如何理解Java中参数传递只能传值?

以前学习C#的时候,是完全在工作岗位上学习,一些底层较为深入的道理都不是很清楚.如今学习了Java,对于Java参数传递只能传值,不能传引用(指针)感到很困惑,在C#中不是常常说把某个引用传递到函数中吗?甚至C#有相当简便的ref.out参数,明明白白的传引用. 经过一番探索,得出的结论表明,Java中我不管你到底是传值还是传引用,只需要记住原生数据类型(值类型)和String作为参数传递的时候,其原本的值都不会发生改变:而引用类型在作为参数传递时,函数中对其的操作,都会反馈到引用所指向的值.

java中参数传递--值传递,引用传递

java中的参数传递--值传递.引用传递 参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递. 在 Java 应用程序中永远不会传递对象,而只传递对象引用.因此是按引用传递对象.Java 应用程序按引用传递对象这一事实并不意味着 Java 应用程序按引用传递参数.参数可以是对象引用,而 Java 应用程序是按值传递对象引用的. Java 应用程序中的变量可以为以下两种类型之一:引用类型或基本类型.当作为参数传递给一个方法时,处理这两种类型的方式是相同的.两

JAVA中参数传递时值传递的机制分析

参数传递是什么? 在C的函数或是JAVA的方法中,向一个函数或方法内部传递一个参数,比如: void fun( int num ){ num+=2 ; } int a = 3 ; fun( a ) ; 这个a就被作为参数传入函数fun()中,作为a,然后返回或者不返回值 回到最初,函数的作用是复用,那么我们希望这个参数传递是什么样的呢?就是假如我们去掉函数的外衣,就让函数变成代码放到之前是函数的地方,那么很自然这里最后b的值会被改变,这可以说是最朴实的参数传递了,自然的样子. 但是人们又发明了另

Java中的参数传递机制

通过前一篇文章的介绍,我们从整体上明白了,Java类中变量的差异性.不同变量在内存中的存储位置,以及变量的生命周期等.今天,我们来看一下Java中参数传递的机制. 形参:方法声明时包含的参数声明 实参:调用方法时,实际传给形参的参数值 Java方法的参数传递机制: Java方法的参数传递只有一种:值传递.所谓值传递,就是将实际参数值的副本,传入方法内,而参数本身不会收到任何影响. PS:传入方法的时实际参数值的复制品,不管方法中对这个复制品如何操作,实际参数本身不会受到任何影响. 基本类型的参数

java中的参数传递是按引用传递还是按值传递

最近去面试,有一个面试官问到java中参数传递的问题,感觉自己对于这一块还是理解的不够深.今天我们就一起来学习一下Java中的接口和抽象类.下面是本文的目录大纲: 一 . 什么是按值传递,什么是按引用传递 二 . java中的参数传递是按值传递还是按引用传递 三.总结 若有不正之处,请多多谅解并欢迎批评指正,不甚感激. 一 . 什么是按值传递,什么是按引用传递 按值调用(call by value) : 在参数传递过程中,形参和实参占用了两个完全不同的内存空间.形参所存储的内容是实参存储内容的一

Java的参数传递问题

Java中方法的参数传递方式是什么? 相信不少人会认为Java和C是一样的:当参数是基本数据类型时采用值传递而参数是非基本数据类型是采用引用传递即地址传递.真的是这样吗? 先看段代码: public class Snippet { public static void main(String[] args) { MyObj obj = new MyObj(); System.out.println(obj.age); process(obj); System.out.println(obj.ag

关于Java中形参与实参的理解

今天阅读了一个写的非常棒的博文,通过此博文再次复习了Java中参数传递的知识(即值传递与引用传递的区别).参考网站http://www.cnblogs.com/binyue/p/3862276.html.下面我将通过次博文记录自己的理解,还望能够帮助再学Java或者复习Java的朋友们. 一.基本类型与引用类型在内存中的保存内容 Java中的变量分为基本类型和引用类型两种.基本类型的变量保存数值本身,而引用类型的变量保存的是引用值,即指向内存空间的地址. 基本类型包括:byte,char,int

关于java中是引用传递还是值传递的问题!!!经常在笔试中遇到,今天终于弄明白了!

关于JAVA中参数传递问题有两种,一种是按值传递(如果是基本类型),另一种是按引用传递(如果是對象).首先以两个例子开始:1)public class Test2 { public static void main (String [] args) { StringBuffer a = new StringBuffer ("A"); StringBuffer b = new StringBuffer ("B"); operate (a,b); System.out.

Java中String类型的参数传递问题的解析

一.引入示例 public class StringAsParamOfMethodDemo { public static void main(String[] args) { StringAsParamOfMethodDemo sapm = new StringAsParamOfMethodDemo(); sapm.testA(); } private void testA() { String originalStr = "original"; System.out.println