我终于忍不住喷一下某些书了,关于Java传引用的XX言论

  凡是说Java对象传的是引用,简直一派胡言,尤其误导我这种Java初学者,更严重的是以前用过C++Java初学者。

  我们都知道Java建立对象一般都是需要这样的格式:

  Object obj = new Object(“初始化”);

  但是在C++中则是可以这样写:

  Object obj = Object(“初始化”);

  少了new,为什么会这样呢?

  因为Java对于声明一个对象建立的是一个指针,相当于C++的这样:

  Object *obj = new Object(“初始化”);

  这下看上去就一样了,事实上就是这样。给函数传递参数时,两种语言没有多少区别。我们先看一个C++例子(为了简化代码,突出重点,变量直接public了):

 

 1 #include <stdio.h>
 2 
 3 class MyTest
 4 {
 5 public:
 6     int x;
 7     MyTest(int x)
 8     {
 9         this->x = x;
10     }
11 };
12 
13 void func(MyTest *&test);
14 
15 int main()
16 {
17     MyTest *test = new MyTest(3);
18     printf("调用前 : %d
", test->x);
19     func(test);
20     printf("调用后 : %d
", test->x);
21     return 0;
22 }
C++代码

 

  很多Java书上说Java中类的对象作为函数参数时传递的是引用,我们就可以这样定义C++func函数,模拟Java书上所说的传递引用的行为:

 

1 void func(MyTest *&test)
2 {
3     test = new MyTest(4);
4 }
C++的func()函数

 

  函数体就一行,这时执行main函数的输出是:

  调用前 : 3

  调用后 : 4

  这个结果在任何C++初学者看来都很显然。

  然后我们写一个“完全一样”的Java版本:

 

1 public class MyTest {
2     public int x;
3     public MyTest(int x) {
4         this.x = x;
5     }
6 }
Java的MyTest类

 

 1 public class Main {
 2     
 3     public static void main(String[] args) {
 4         MyTest test = new MyTest(3);
 5         System.out.println("调用前 : " + test.x);
 6         func(test);
 7         System.out.println("调用后 : " + test.x);
 8     }
 9     
10     private static void func(MyTest test) {
11         test = new MyTest(4);
12     }
13 }
Java的main与func函数

  这下输出却另我们大失所望:

  调用前 : 3

  调用后 : 3

  竟然不一样,说好的传引用呢?为什么形参的改动没有影响到实参呢?简直了。为什么跟C++这样写效果一样啊:

 

1 void func(MyTest *test)
2 {
3     test = new MyTest(4);
4 }
C++没有引用的func函数

 

  所以Java完全没有引用这种东西!一切都是值传递,我查资料得出的结论是:C++只是把引用符号(&)解析成了指针,也就相当于这样写func函数:

 

1 void func(MyTest **test)
2 {
3     *test = new MyTest(4);
4 }
C++指向指针的指针

 

  这就是为什么做到了引用,其实传的还是值,只不过是传的指针的指针,就算是这样,传的还是这个指针的副本,只是里面保存的内容一样而已。

  我被误导了很久,因为这样写Javafunc函数可以:

 

1 private static void func(MyTest test) {
2     test.x = 4;
3 }
Java的func函数

 

  但是这样却不行:

1 private static void func(MyTest test) {
2     test = new MyTest(4);
3 }
Java的func函数

  所以标题写的比较偏激,表达一下纠结的心情。我个人认为正确的说法应该是:Java是值传递,类对象变量都是一个对象指针,作为参数传到函数中跟传基本类型一样,都是复制了一份副本传递的,所以可以改变其成员变量的值,但不能改变其自身。希望跟我一样的初学者没有在某些书的误导下陷入歧途!

 

 

 

 

 

原文地址:https://www.cnblogs.com/wolfred7464/p/3493797.html