首先需要明白对象和对象引用之间的区别,建议阅读Matrix海子 ,ITeye 两篇帖子。
对于Java值传递问题,本文主要参考了四个帖子,理解容易到困难是 wugongzi,Intopass的回答,沉默王二,彻底解决java值传递 ,最后一个解释的比较细致,没有细看。
1.1 基本数据类型与引用类型的区别
int num=10;
String str="hello";
- num是基本类型,值就直接保存在变量num中;
- str是对象引用变量,只保存实际对象的内存地址,指向实际对象,实际对象保存着内容 "hello"
1.2 赋值操作符 ==
num=20; //直接改变变量的值,原来的值被覆盖掉
str="java"; // 赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉,但是原来的对象不会被改变(没有被任何引用指向的对象会被回垃圾机制收)
1.3 值传递和引用传递
值传递:在方法被调用时,实参通过形参把它的内容副本传入方法内部,此时形参接收到的内容是实参值的一个拷贝,因此在方法内对形参的任何操作,都仅仅是对这个副本的操作,不影响原始值的内容。基本数据类型都是值传递。
引用传递:”引用”也就是指向真实内容的地址值,在方法调用时,实参的地址通过方法调用被传递给相应的形参,在方法体内,形参和实参指向同一块内存地址,对形参的操作会影响的真实内容。
引用传递也是值传递,只不过值为对象的引用(拷贝的是对象的内存地址),因此我觉得所谓的引用传递并不存在,只是在实参传入形参时,传递的都是一个副本,而不是内容本身。
1.4 代码例子
1.4.1 基本数据类型
public class PrimilitaryPass {
public static void valuePass(int age,float weight) {
System.out.println("传入的age值:"+age);
System.out.println("传入的weight值:"+weight);
age=23;
weight=60;
System.out.println("修改后的age值:"+age);
System.out.println("修改后的weight值:"+weight);
}
public static void main(String[] args) {
int age=10;
int weight=50;
valuePass(age,weight);
System.out.println("方法执行后main()的age:"+age);
System.out.println("方法执行后main()的weight:"+weight);
}
}
1.4.2 引用类型(对象)
Person类
package ValuePass;
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
PersonTest1.java
package ValuePass;
public class PersonTest {
public static void PersonPass(Person person) {
System.out.println("传入person的name:" + person.getName());
person.setName("伏地魔");
System.out.println("方法内重新赋值后的name:"+person.getName());
}
public static void main(String[] args) {
// 1.part1
Person p = new Person();
p.setName("哈利波特");
p.setAge(4);
PersonPass(p);
System.out.println("方法执行后的name:"+p.getName());
}
}
PersonTest2.java
package ValuePass;
public class PersonTest2 {
public static void PersonPass(Person person) {
System.out.println("传入person的name:" + person.getName());
person = new Person();//新增代码
person.setName("伏地魔");
System.out.println("方法内重新赋值后的name:"+person.getName());
}
public static void main(String[] args) {
// 1.part1
Person p = new Person();
p.setName("哈利波特");
p.setAge(4);
PersonPass(p);
System.out.println("方法执行后的name:"+p.getName());
}
}
结合上述的前两个帖子就很容易理解基本数据类型和引用类型代码的结果