Java传递参数只有一种 :值传递 而没有引用传递
一般根据传递类型来分类 可以分为 值类型数据 和 引用数据类型
值类型是原始数据类型 包括 int,byte,char short long,boolean,float,double
引用类型就是一般的class类 当然也包括原始数据的封装类型 比如int的
封装类型为Integer
比如对象的引用关系是这样的
List list=new ArrayList();
如上一段代码会产生两个对象 :引用对象(存在于栈中),实例对象(存在于堆中)
引用对象的地址指向了实例化对象的地址,
如果方法调用中传入的是引用对象才属于真正的引用传递
一般情况下 举个例子:
public class TestJava {
public static void add(TestJava java){
java=new TestJava();
}
public static void main(String[] args) {
TestJava java=null;
add(java);
System.out.println(java);
}
}
输出结果 null
其实可以这么去理解:
调用方法时 同时也会产生一个引用对象,产生的新引用对象 同时也指向实例对象 public static void add(TestJava java) 相当于该方法中的TestJava java
在方法中 新的引用地址指向了一个新创建的对象 ,而旧的
java=new TestJava(); 里面的java 还是指向的null对象 所以方法传递的时候 实际是传递实例化对象和创建了一个新的引用,而不是旧的引用对象的传递所以不属于 引用传递
看下面的例子
public class TestJava {
String name=null;
public static void add(TestJava java1){
java1.name="liaomin";
}
public static void main(String[] args) {
TestJava java=new TestJava();
java.name="huqun";
add(java);
System.out.println(java);
}
}
输出结果 liaomin
上面的例子 可以进一步确认上面的观点
TestJava java=new TestJava();
创建了一个引用对象 和一有个实例化对象
引用对象指向了 实例对象
public static void add(TestJava java1)
创建了一个新引用对象
add(java);
调用的时候 同时java1引用对象指向了实例化对象
java1.name="liaomin";
改变了 java1的值 实际上是改变了实例化对象的值
Java引用对象也是指向了 实例化对象 所以他的值
也会改变
如果觉得理由在不充分 在在看下面的例子
看下面的例子
public class TestJava {
String name=null;
public static void add(TestJava java1){
Java1=new TestJava();
java1.name="liaomin";
}
public static void main(String[] args) {
TestJava java=new TestJava();
java.name="huqun";
add(java);
System.out.println(java);
}
}
输出结果 huqun;
TestJava java=new TestJava();
创建了一个引用对象java 和一有个实例化对象 new TestJava()
引用对象指向了 实例对象
public static void add(TestJava java1)
创建了一个新引用对象
add(java);
调用的时候 同时java1引用对象指向了实例化对象
Java1=new TestJava();
Java1指向了 新创建的实例化对象
java1.name="liaomin";
改变了 java1的值 实际上是改变了新实例化对象的值,而不是改变
的旧的实例化对象 因为他指向了别人
原Java引用对象也是指向的是以前实例化对象 所以他的值
不会改变
常量类型的引用
public class TestJava {
public static void add(Integer inte){
inte=2;
}
public static void main(String[] args) {
Integer in=new Integer(1);
add(in);
System.out.println(in);
}
}
任何原始数据类型及原始数据类型的封装类 作为参数传递时
无论怎么在方法中修改都不会影响原始的值 ,因为在传递时
传递的对象的常量值 而不是 地址了 所以不会改变,可以理解
为实例化对象在堆内存中储存的常量值 而不是地址
比如 Integer it=new Integer(3);
栈内存中放的是 it地址 对内存中放的是 3
It地址指向的是3
看一下 String 的 问题
public class TestJava {
public static void main(String[] args) {
String a="234";
String b=new String("234");
String c="234";
System.out.println(a==b);
System.out.println(c==b);
System.out.println(a==c);
}
}
a="234";
b=”234”
a==b比较地址 地址绝对是一样的 比较的是实例化对象的地址 而不是引用的地址
b=”234”是 首先去查看一下 堆内存中是否有 “234”这个常量 如果有 则指向该地址
没有就创建一片地址
C=new String(“234”) 很明显重新开辟了一片心地址 和上面的都不相等