这个例子阐述了对象参数不能改变其引用的对象,但可以改变其状态。
有个疑问,如果参数是List,就可以改变。 请问这是为什么? 
求解。ParamTest.javapublic 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.javapublic 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;
}
}

解决方案 »

  1.   

    http://yqsshr.blog.51cto.com/469059/147695
      

  2.   

    这个例子阐述了对象参数不能改变其引用的对象,但可以改变其状态
    有个疑问,如果参数是List,就可以改变。 请问这是为什么?  
    求解。红色部分是很关键的,在java里,方法内部不能改变方法外部变量的指向,但是可以改变方法外部变量指向的对象,List也不例外
    举个例子
    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也能感知变化
        }
    }
    从上面的change1和change2方法知道,change1改变了参数的指向,即执行 参数=xxx ,也就是给参数重新赋值的操作,所以方法外的变量不受任何影响。从中可以知道,基本类型,都是通过赋值的方式来改变参数的值的,所以基本类型的修改不影响方法外的变量,而引用类型的变量,如果也是采用赋值的方式,那么也不影响方法外的变量,只有调用引用类型的方法来改变所以用的对象的状态,方法外部的变量才能感知变化,也就是方法外部的变量才会改变(这里要知道改变的是变量所引用的对象,变量本身是不变的)
    这就是红色文字所要说明的意思,LZ再好好体会吧
      

  3.   

    Google搜“java 值传递”引用某人的霸道回复:
    1、Java中只有值传递,Java创始人说的,其他的说我们都不听,也不争论了。
    2、class A{int i;int j}这些i、j在哪里存储?告诉涂传滨,在heap中。
      

  4.   

    List是通过内部引用数据结构实现的,通过传递List引用对象改变的是同一个List列表结构
      

  5.   

    java 只有值传递,没有引用传递。所谓的引用传递传的也是引用的值。
      

  6.   

    http://blog.csdn.net/niuniu20008/article/details/2953785
    希望对楼主有所帮助