日期:2014-05-20  浏览次数:20757 次

谁来解释,基本类型与对象参数传递问题?
这个例子阐述了对象参数不能改变其引用的对象,但可以改变其状态。
有个疑问,如果参数是List,就可以改变。 请问这是为什么? 
求解。

ParamTest.java
Java code

public class PramTest {

    public static void main(String[] args) {
        /**
         * Test 1: 方法无法修改数值参数.
         */
        System.out.println("Testing tripleValue");
        double percent = 10;
        System.out.println("Before: percent="+percent);
        tripleValue(percent);
        System.out.println("After: percent="+percent);
        /**
         * Test 2: 方法可以改变对象参数状态
         */
        System.out.println("\nTesting tripleSalary");
        Employee harry = new Employee("Harry", 50000);
        System.out.println("Before: salary="+harry.getSalary());
        tipleSalary(harry);
        System.out.println("After: salary="+harry.getSalary());
        /**
         * Test 3: 方法不能将新的对象赋给对象参数
         */
        System.out.println("\nTesting swap:");
        Employee a = new Employee("Alice", 70000);
        Employee b = new Employee("Bob", 60000);
        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 tipleSalary(Employee x){
        x.raiseSalary( 200 );
        System.out.println("End of method: salay="+ x.getSalary());
    }
    
    public static void swap(Employee x, Employee y){
        Employee temp = x;
        x = y;
        y = temp;
        System.out.println("End of method: x="+x.getName());
        System.out.println("End of method: y="+y.getName());
    }
}



Employee.java
Java code

public class Employee {

    private String name;
    private double salary;
    
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public void raiseSalary(double byPrecent){
        double raise = salary * byPrecent / 100;
        salary += raise;
    }
    
    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }
}



------解决方案--------------------
http://yqsshr.blog.51cto.com/469059/147695
------解决方案--------------------
值传递和引用传递的问题
------解决方案--------------------
这个例子阐述了对象参数不能改变其引用的对象,但可以改变其状态。
有个疑问,如果参数是List,就可以改变。 请问这是为什么?
求解。

红色部分是很关键的,在java里,方法内部不能改变方法外部变量的指向,但是可以改变方法外部变量指向的对象,List也不例外
举个例子
Java code
public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("test");
        change1(list);
        System.out.println("change1:" + list);
        change2(list);
        System.out.println("change2:" + list);
    }
    public static void change1(List<String> list) {
        //首先要知道,每个方法都有自己的栈,每个方法内部的变量属于自己的栈,
         //也就是说change1方法的list和main方法的list不是同一个变量
         //但是它们都指向同一个List对象,也就是说main方法的list引用一个List对象,
         //change1方法的list也引用了和main方法的list相同的List对象

        list = new ArrayList<String>(); //要注意这个地方和change2方法的区别
        //所以这里改变了方法内部的list指向,让它指向一个新的List对象,
         //但是方法外部的list的指向并没有改变,
         //也就是说这时候方法内部的list引用的对象已经和方法外部的list引用的对象不是同一个了
        list.add("change1"); /
        //所以这里对list所作的任何操作只影响方法内部的list所引用的对象,
         //对方法外部的list所引用的对象没有任何影响,所以方法外部的list没有任何变化
    }

    public static void change2(List<String> list) {
        list.add("change2");
        //而这个方法中,方法内部的list的指向没有发生任何改变
         //还是和方法外部的list引用相同的一个对象
         //所以对方法内部的list所作的任何操作都会影响list所引用的对象
         //因为方法外部的list也引用该对象,该对象被方法内部的list改变了,
         //所以方法外部的list也能感知变化
    }
}