在一般程序设计语言中,按值调用表示的是该方法接受到的是调用者提供的值。而按引用调用表示方法接收的是调用所对应的变量值。
在Java程序设计中总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝。
方法参数共有两种类型:
1.基本数据类型(数字、布尔值)。(值传递)
2.对象引用。(引用传递)
此处主要通过两端代码来讨论值传递和引用传递对原数据状态锁产生的影响:
public static void main(String[] args) {
//值传递不可改变原值
System.out.println("***********测试值传递*************");
double percent = 10;
System.out.println("Before percent = " + percent);
tripleValue(percent);
System.out.println("After percent = " + percent);
/*
* ***********测试值传递*************
Before percent = 10.0
End of the method :30.0
After percent = 10.0 //因为传递的只是percent的一个拷贝,所以在
方法结束后 x不在使用,原来的percent的值也不会受到改变
//其实percent和x是虚拟机栈两个栈帧中局部变量表里的一部分,不会相互影响
*/
//引用传递可以改变一个对象参数的状态
System.out.println("********引用传递******");
Employee harry = Employee.getEmployee("Harry", 50000);
System.out.println("Before: salary=" + harry.getSalary());
tripleSalary(harry);
System.out.println("After: salary=" + harry.getSalary());
/*
* ********引用传递******
Before: salary=50000.0
End of method: salary=150000.0
After: salary=150000.0
//引用传递虽然也进行了拷贝,但是拷贝的内容是该对象的引用,两个引用指向对内存中的同意对象
若通过其中任意一个引用对该对象的参数状态进行改变,则该对象利索当然发生变化
*/
}
private static void tripleSalary(Employee x) {
x.raiseSalary(200);
System.out.println("End of method: salary=" + x.getSalary());
}
private static void tripleValue(double x) {
x = 3 * x;
System.out.println("End of the method :" + x );
}
有上述程序不能理解值传递和引用传递的区别
//上面程序所用到的Employee类
public class Employee {
private String name;
private double salary;
private Employee(String name, double salary){
this.name = name;
this.salary = salary;
}
public static Employee getEmployee(String name, double salary){
return new Employee(name, salary);
}
public String getName(){
return name;
}
public double getSalary(){
return salary;
}
public void raiseSalary(double byPercent) {
double raise = salary*byPercent/100;
salary += raise;
}
}
实际上,单纯的说Java是进行按值调用的是有一定的问题。因为java程序语言不能通过方法进行两个对象的交换
原因是方法执行完成之后交换的是两个对象引用的拷贝,而原来的引用任然没有收到污染
**
1.一个方法不能修改一个基本数据类型的参数(即数值型和布尔型);
2.一个方法可以改变一个对象参数的状态;
3.一个方法不能让对象参数引用一个新的对象。