##基本数据类型##
对于基本数据类型,如 int long bool 等 是值传递,传递时将值复制一份给形参,如下:
package com.loftor;
public class Argument {
public static void main(String[] args) {
int value = 1;
change(value);
System.out.print(value); //输出结果为1
}
public static void change(int value){
value=2;
}
}
##引用类型##
对于引用类型如 User 等 传递的是引用,传递是将对象的地址复制给形参 如下
package com.loftor;
class User{
public String name;
}
public class Argument {
public static void main(String[] args) {
User user = new User();
user.name="小明";
change(user);
System.out.print(user.name); //输出小红
}
public static void change(User user){
user.name="小红";
}
}
调试时可以看到如下的结果
@后面跟的参数可以理解为地址,在为进入change方法前的值为454
进入change后的值依然为454,说明这两个是同一个对象,传参时只是将对象的地址复制给了方法的形参。
##小结##
基本类型在传递时传递的是参数的值,引用类型(如类)传递的是对象的地址。
##特殊但又不特殊的情况##
但是有一个例外,那就是String,Long等简单的Object,在Java中,String是一个引用类型,但是在作为参数传递的时候表现出来的却是基本类型的特性,即在方法中改变了String类型的变量的值后,不会影响方法外的String变量的值。
这个情况我们还是用修改了一下代码做说明
package com.loftor;
public class Argument {
public static void main(String[] args) {
String value = "小明";
change(value);
System.out.print(value);
}
public static void change(String value){
String str="小红";
value=str;
}
}
在未进入change方法前,value 的指向的地址为 453
进入方法后 形参 value 的指向的地址依然为 453 说明形参复制了实参的地址
其中str变量的指向的地址为 454
value=str;这行很关键,出现以上错觉的原因就是String的赋值,java里赋值的做法是将地址赋值给变量,因为value指向的地址453,现在将它赋值后,指向的地址将变成str的地址454,只是指向的地址进行了改变,对于地址453上存的值便没有发生改变,change方法的形参在change生命周期结束后便回收了,而在方法change外面的value的指向地址便没有发生改变还是指向453,所以value的值不会改变。
类似C中的两个指针,一个是change外面的value,一个是change里面的value,一开始他们指向同一个地址453,后来change里面的value指向了454,便没有对453上面存储的值进行改变,所以外面的value的值不会发生改变。
##结论##
java中常量存储在常量池中。这些常量的地址和值是固定的,只会增加,不会对现有地址上的值做出修改。同一个值对应的地址是一样的。

以上图片可以看到str1和str2的地址是一样的
基本类型的值都是常量,看起来是传值,但是实际上传的是还是这个常量的地址,而基础类型变量可以理解为一个指针,指向的都是常量的地址,根据上面的规则,要想改变一个基础类型的变量的值,只能通过更改变量指向的地址。所以只要基础类型变量的地址没有改变,那么他们指向的地址就不会改变,这也就是为什么基础类型看起来像是是传值。