java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解相关的知识,希望对你有一定的参考价值。

head first java里写到“java是通过值传递的,也就是通过拷贝传递”,由此得出结论,方法无法改变调用方传入的参数。该怎么理解呢?

看例子:

public class Test1 {

public static void main(String[] args) {
 int x = 7;
 System.out.println("传入方法之前:x="+x);
 addOne(x);
 System.out.println("传入方法之后:x="+x);
}
private static void addOne(int y){
 y++;
 System.out.println("传入参数被改变:y="+y);
}

}

输出:

传入方法之前:x=7
传入参数被改变:y=8
传入方法之后:x=7

因为方法改变的只是值的拷贝(变量y的值),所以对原值(变量x的值)不产生影响。所以x的值在被传入方法前后都为7.

那么在看下面的例子

public class Dog {
 String name;
 int age;

省略get,set

}

public class Test2 {

public static void main(String[] args) {
 Dog yellow = new Dog();
 yellow.setName("大黄");
 System.out.println("传入方法之前:yellow的名字是"+yellow.getName());
 changeName(yellow);
 System.out.println("传入方法之后:yellow的名字是"+yellow.getName());
}
private static void changeName(Dog white){
 white.setName("小白");
 System.out.println("传入参数被改变:white的名字是"+white.getName());
}

}

传入方法之前:yellow的名字是大黄
传入参数被改变:white的名字是小白
传入方法之后:yellow的名字是小白

yellow的名字在被传入方法之前是“大黄”,传入方法之后却变成了“小白”,那么“方法无法改变调用方传入的参数”的说法是否仍然成立呢?

答案是肯定的。

Dog yellow与int i 的不同之处,int i 是primitive主数据类型变量,变量值就是7,所以拷贝给y的值是7,addOne方法执行前后x始终等于7。而前者是对象引用变量(yellow是获取Dog对象的位表示法,即所谓的指针),所以拷贝给Dog white的只是一个指针,yellow和white同时指向了堆内存中的同一个Dog对象。changeName方法改变了被指向的Dog对象的实例变量name的值,但是yellow指针始终指向这个Dog对象,被传入的值(指针)没有发生变化。

以上是关于java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解的主要内容,如果未能解决你的问题,请参考以下文章

详解Java技术的深拷贝和浅拷贝

PHP 数组的拷贝是按值传递 or 按引用传递

Jvm(31),理解升级----通过JVM内存模型深入理解值传递和引用传递两种方式

Java 并发编程 - 2

原型模式,浅拷贝,深拷贝

使用 JNI(更具体地说是 Android NDK)时,Java 是不是通过引用或值传递给 C