<Core Java> 4.5 方法参数

1、专业术语:
值调用(call by value)表示方法接收的是调用者所提供的值。
引用调用(call by reference)表示方法接收的是调用者所提供的变量地址。
方法可以修改传递引用所对应的变量,但是不能修改传递值调用所对应的变量值

2、Java中总是采用值调用。即方法得到的是所有参数值的一个拷贝值,方法的作用效果均是在这个拷贝值上体现,与原本真实值无关。所以Java中的方法不能修改传递给他的任何参数变量。
例如,假定一个方法试图将参数值增至3倍:
public static void tripleValue(double x) {
    x = 3 * x;
}
double percent = 10;
tripleValue(percent);
这个方法结束后percent仍为10,而对象引用参数x的值为30.但是方法结束后参数变量x不再使用,所以percent仍为10.
具体执行过程:
(1)x被初始化为percent值的一个拷贝(即x = 10)
(2)x被方法作用,值变为30.此时percent为10
(3)方法结束后,x不再使用

注意:方法参数有两种类型:基本数据类型(数字、布尔值)和对象引用。已经知道方法不能修改基本类型参数,但可以修改引用参数。

3、下面这个方法是将雇员薪金提高两倍:
public static void tripleSalary(Employee x) {
    x.raiseSalary(200);
}
harry = new Employee;
tripleSalary(harry);
执行过程:
(1)x被初始化为harry的拷贝值,这里是一个引用对象;
(2)raiseSalary犯法作用在这个引用对象上。x和harry同时应用的Employee对象的薪金提高了200%
(3)方法结束后,参数变量x不再使用,但是harry继续应用被raiseSalary方法作用后的Employee对象

4、很多语言提供两种参数传递方式:值调用和引用调用。Java对对象采用的不是是引用调用。例如:
一个交换两个雇员对象的方法:
public static void swap(Employee x, Employee y) {
    Employee temp = x;
    x = y;
    y = temp;
}
如果Java采用引用调用就应该实现交换数据的效果:
Employee a = new Employee("A");
Employee b = new Employee("B");
swap(a, b);
实际上swap方法的参数x和y被初始为两个对象的拷贝,方法实现的是两个拷贝的交换。方法结束后x和y被丢弃,最终白费力气。
说明:
Java对对象采用的不是引用调用而是值调用。

5、总结下Java中方法参数的使用情况:
一个方法不能修改基本数据类型的参数;
一个方法可以改变一个对象的参数;
一个方法不能实现让对象参数引用一个新的对象。

6、本节源代码,例4-4.
运行效果:
Testing tripleValue: 
Before: percent=10.0
End of method: x=30.0
After: percent=10.0

Testing tripleSalary
Before: percent=5000.0
End of method: x=15000.0

Testing swap: 
Befor: a=Alice
Befor: b=Bob
After: x=Bob
After: y=Alice
After: a=Alice
After: b=Bob

ParamTest.java:
  1. package com.vincent.javacore.paramtest;  
  2.   
  3. public class ParamTest {  
  4.     public static void main(String[] args) {  
  5.         //测试一:试图将percent提高两倍,失败了  
  6.         System.out.println("Testing tripleValue: ");  
  7.         double percent = 10;  
  8.         System.out.println("Before: percent=" + percent);  
  9.         tripleValue(percent);  
  10.         System.out.println("After: percent=" + percent);  
  11.           
  12.         //测试二:成功的将一个雇员的薪金提高了两倍  
  13.         System.out.println("\nTesting tripleSalary");  
  14.         Employee harry = new Employee("harry"5000);  
  15.         System.out.println("Before: percent=" + harry.getSalsry());  
  16.         tripleSalay(harry);  
  17.           
  18.         //测试三:演示swap失败的效果  
  19.         System.out.println("\nTesting swap: ");  
  20.         Employee a = new Employee("Alice"7000);  
  21.         Employee b = new Employee("Bob"6000);  
  22.         System.out.println("Befor: a=" + a.getName());  
  23.         System.out.println("Befor: b=" + b.getName());  
  24.         swap(a, b);  
  25.         System.out.println("After: a=" + a.getName());  
  26.         System.out.println("After: b=" + b.getName());  
  27.     }  
  28.   
  29.     private static void swap(Employee x, Employee y) {  
  30.         Employee temp = x;  
  31.         x = y;  
  32.         y = temp;  
  33.         System.out.println("After: x=" + x.getName());  
  34.         System.out.println("After: y=" + y.getName());  
  35.           
  36.     }  
  37.   
  38.     private static void tripleSalay(Employee x) {  
  39.         x.raiseSalary(200);  
  40.         System.out.println("End of method: x=" + x.getSalsry());  
  41.           
  42.           
  43.     }  
  44.   
  45.     private static void tripleValue(double x) {  
  46.         x = 3 * x;  
  47.         System.out.println("End of method: x=" + x);          
  48.     }  
  49.   
  50. }  
Employee.java
  1. package com.vincent.javacore.paramtest;  
  2.   
  3. public class Employee {  
  4.     private String name;  
  5.     private double salary;  
  6.   
  7.     public Employee(String n, double s) {  
  8.         name = n;  
  9.         salary = s;  
  10.     }  
  11.     public String getName() {  
  12.         return name;  
  13.     }  
  14.       
  15.     public double getSalsry() {  
  16.         return salary;  
  17.     }  
  18.       
  19.     public void raiseSalary(double byPercent) {  
  20.         double raise = salary * byPercent / 100;  
  21.         salary += raise;  
  22.     }  
  23.   
  24. }  
posted @ 2013-02-27 18:15  vincent_hv  阅读(165)  评论(0编辑  收藏  举报