java的值传递和引用传递

一:搞清楚 基本类型 和 引用类型的不同之处

int num = 10;
String str = "hello";

java 对象赋值对象 java对象赋值是地址吗_java

如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为"引用",引用指向实际对象,实际对象中保存着内容。

二:搞清楚赋值运算符(=)的作用

num = 20;
str = "java";

对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。

对于引用类型

str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变(重要)。

如上图所示,"hello" 字符串对象没有被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)

java 对象赋值对象 java对象赋值是地址吗_字符串_02

 

一个段有趣和令人困惑的代码

1  public static void main(String[] args){
2         String str = new String("ab");
3         change(str);
4         System.out.println(str);
5     }
6 
7 public static void change(String str){
8         str = "cd";
9     }

结果为:ab

 

常见的困惑问题

x存储指向堆中的“ab”字符串的引用。所以,当x被作为参数传递到change()方法时,它仍然指向堆中“ab”,像下面这样:

java 对象赋值对象 java对象赋值是地址吗_字符串_03

因为java是按值传递的(pass-by-value), x的值是“ab”的引用。当方法的change()被调用,它会创建一个新的“cd”的对象,而x现在是指向“cd”像下面这样:

java 对象赋值对象 java对象赋值是地址吗_java 对象赋值对象_04

 

 
这似乎是一个相当合理的解释。他们明确表示,Java是总是传递按值。但是,错在哪里呢?

 

代码真正做了些什么呢?

上面的解释有几个错误。为了容易理解这一点,这是一个好主意,简单地描述整个过程。
当字符串“ab”被创建,java分配存储字符串对象所需的内存空间。然后,将对象分配给变量x,该变量是被实际分配的引用对象。此引用是该对象被存储在内存的地址。
变量x包含一个字符串对象的引用。 x不是引用本身!它是用于存储一个引用(内存地址)的变量。
Java是仅仅是按值传递。当x传递给change()方法,x的(引用)值的副本被传递。方法change()创建另一个对象“cd”,它有一个不同的引用。它是被改变的x副本指向“cd”的变量,而不是x引用本身。

下面的图表展现了真实的过程:

 

总结:实际上JAVA在方法里传递的只是对象的副本。

 

值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量.

 

引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。

 

一般认为,java内的基础类型数据传递都是值传递. java中实例对象的传递是引用传递