欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CoreJava读书笔记--对象与类(四)--方法参数

程序员文章站 2024-03-15 23:17:48
...

方法参数

在程序设计语言中,将参数传递给方法(或函数)有两种传递方式:

①按值调用(call by value):表示方法接收的是调用者提供的值。

②按引用调用(call by reference):表示方法接收的是调用者提供的变量地址。

按引用调用时,方法可以修改传递引用所对应的变量值;按值调用时,方法不能修改传递值调用所对应的变量值。

而Java程序设计语言总是采用按值调用,也就是说:方法得到的是所有参数值得一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。

我们假定一个方法可以将参数值增加至3倍:

package Test;

public class Demo1 {
	public static void main(String[] args) {
		double percent = 10;
		tripleValue(percent);
		System.out.println(percent);
	}
	public static void tripleValue(double x) {
		x=3*x;
	}
}

CoreJava读书笔记--对象与类(四)--方法参数

我们可以看到,调用这个方法后,percent值还是10,并没有发生改变。

CoreJava读书笔记--对象与类(四)--方法参数

具体执行过程:

1)x被初始化为percent值得一个拷贝(也就是10);

2)x被乘以3后等于30。但是percent仍然是10;

3)这个方法结束后,参数变量x不再使用

从上面可以看出当参数是基本数据类型的时候,方法是不能修改基本数据类型的参数的。但是我们知道,方法参数除了是基本数据类型外,还可以是对象的引用作为参数,那么这样的参数又是什么情况呢?

实现一个将员工薪金提高两倍的操作:

public static void tripleSalary(Employee e)
{
  e.raiseSalary(200);
}
当调用该方法时:
harry = new Employee(...);
tripleSalary(harry);

具体执行过程为:

1)x被初始化为harry值得拷贝,这里是一个对象的引用

2)raiseSalary方法应用于这个对象的引用。x和harry同时引用的那个Employee对象的薪金提高了200%

3)方法结束后,参数变量x不再使用。当然,对象变量harry继续引用那个薪金增至3倍的雇员对象。

我们可以看到,实现一个改变对象参数状态的方法并不难,因为方法得到的是对象引用的拷贝,对象的引用及其他的拷贝还是引用了这个对象。

举个反例:编写一个交换两个雇员对象的方法
public static void swap(Employee x,Employee y)
{
  Employee temp = x;
  x=y;
  y=temp;
}

如果Java对对象采用的是按引用调用,那么上述方法就应该能实现交换数据的效果:

Employee a = new Employee("Alice",....);
Employee b = new Employee("Bob",....);
swap(a,b);

但是,方法并没有改变存储在变量a,b中对象的引用,swap方法的参数x和y都初始化为两个对象引用的拷贝,而该方法交换的只是这两个拷贝。并且在方法结束时,x和y都没有了,而原来的a和b还是引用方法调用前的对象

----------------------------------------------------------------------------------------------------------------------------------

总结:所以上述过程说明,Java程序设计语言采用的不是引用调用,实际上,对象引用是按值传递的。Java中方法参数的使用情况:

①一个方法不能修改一个基本数据类型的参数

②一个方法可以改变一个对象参数的状态

③一个方法不能让对象参数引用一个新的对象

package CoreJava;

/**
 * This program demonstrates parameter passing in Java
 * call by value
 * @author 弓长小月
 *
 */
public class ParamTest {
	public static void main(String[] args) {
		/*
		 * Test1:Methods can't modify numeric parameters;
		 */
		System.out.println("Testing tripleValue:");
		double percent = 10;
		System.out.println("Before : percent="+percent);
		tripleValue(percent);
		System.out.println("After : percent="+percent);
		
		/*
		 * Test2:Methods can change the state of object parameters
		 */
		System.out.println("\nTesting tripleSalary:");
		Employee3 harry = new Employee3("Harry",50000);
		System.out.println("Before salary : salary = "+harry.getSalary());
		tripleSalary(harry);
		System.out.println("After salary : salary = "+harry.getSalary());
		
		/*
		 * Test3:Methods can't attach new object to object parameters
		 */
		System.out.println("\nTesting swap");
		Employee3 a = new Employee3("Alice",70000);
		Employee3 b = new Employee3("Bob",50000);
		System.out.println("Before : a="+a.getName());
		System.out.println("Before : b="+b.getName());
		swap(a,b);
		System.out.println("After : a="+a.getName());
		System.out.println("After : b="+b.getName());
	}
	public static void tripleValue(double x) {
		x=3*x;
		System.out.println("End of method : x = "+x);
	}
	public static void tripleSalary(Employee3 x) {
		x.raiseSalary(200);
		System.out.println("End of method : salary="+x.getSalary());
	}
	public static void swap(Employee3 x,Employee3 y) {
		Employee3 temp = x;
		x=y;
		y=temp;
		System.out.println("End of method : x= "+x.getName());
		System.out.println("End of method : y= "+y.getName());
	}
}
class Employee3{
	private String name;
	private double salary;
	
	public Employee3(String n,double s) {
		this.salary=s;
		this.name=n;
	}
	public String getName() {
		return name;
	}
	public double getSalary() {
		return salary;
	}
	public void raiseSalary(double byPercent) {
		double raise = salary*byPercent/100;
		salary+=raise;
	}
}

CoreJava读书笔记--对象与类(四)--方法参数