package wit.test;

public class Test2
{
public static void main(String[] args) {
   //传对象
   AA a =new AA();
   a.n = 10;
   System.out.println("调用函数(参数是对象)前:"+a.n);
   f(a);
   System.out.println("调用函数(参数是对象)后:"+a.n);

   //传的是基本类型
   int n = 10;
   System.out.println("调用函数(参数是基本类型int)前:"+n);
   f(n);
   System.out.println("调用函数(参数是基本类型int)后:"+n);

   Integer nn = new Integer(10);
   System.out.println("调用函数(参数是基本类型Integer)前:"+nn);
   f(nn);
   System.out.println("调用函数(参数是基本类型Integer)后:"+nn);

   //传的String
   String s = new String("ou");
   System.out.println("调用函数(参数是String)前:"+s);
   f(s);
   System.out.println("调用函数(参数是String)后:"+s);

   //传递的StringBuffer
   StringBuffer sb =new StringBuffer("ouyang");
   System.out.println("调用函数(参数是StringBuffer)前:"+sb);
   f(sb);
   System.out.println("调用函数(参数是StringBuffer)后:"+sb);
   //传的是String[]
   String[] ss = new String[3];
   ss[0] = "欧";ss[1]="阳";
   System.out.println("调用函数(参数是String[])前:"+ss[0]);
   f(ss);
   System.out.println("调用函数(参数是String[])后:"+ss[0]);
  
   //传递的是int[]
   int[] ii = {10,20,30};
   System.out.println("调用函数(参数是int[])前:"+ii[0]);
   f(ii);
   System.out.println("调用函数(参数是int[])后:"+ii[0]);


  
}
//传对象
public static void f(AA a) {
   a.n = 20;
}
//传的基本类型
public static void f(int n) {
   n = 20;
}
public static void f(Integer n) {
   n = 20;
}
//传的String[]
public static void f(String[] a) {
   a[0]="平";
}
//传的String
public static void f(String a) {
   a = "ouyangping";
}
//传的int[]
public static void f(int a[]) {
   a[0] = 20;
}
//传的StringBuffer
public static void f (StringBuffer sb) {
   sb.append("ping");
}
};
class AA
{
public int n ;
};

 


/*************************

* 总结

*************************/// Java函数参数是值传递的。  

//. 如果参数是基本类型,函数不能改变参数的值。(包括 String)  

//-----传递过去的是值传递,传递的是  

//. 如果参数是对象,函数可以改变参数的属性(包括StringBuffer,int[]等)。  

//. 如果参数是对象,函数不能使参数指向新的对象。//这很好解释,对于基本类型诸如int,传递进去的是存放int值的“内存单元”的一个copy,所以函数swap里面的int和外面的int根本就不是一个东西,当然不能反射出去影响外面

//

//的int。而对于对象类型,我们同样可以这样认为,传递进去的是存放对象类型的指针的“内存单元”一个copy(虽然Java里面没有指针的概念,但这并不妨碍我们理解)。这样,

//

//在swap函数里面,对其指针本身的值做任何操作当然不会影响外面的Integer,因为interger1和interger2的“内存单元”里面的值是不变的,其指向的对象类型也是没有变的。

//

//然后这里需要说明一个问题,就是StringBuffer这种类型的对象了。因为其内容是可以改变的,所以change函数里面的“指针”通过类似“*”的操作,改变了StringBuffer对象的

//

//本身,就显而易见了。(StringBuffer对象本身只有一个副本)

//

//然后说C++了,里面的基本类型的诸如int的值传递大家都了然于胸,就不在这里废话了。然后另一种值传递可以称为指针引用传递  

 

,《Core Java™ 2: Volume I - Fundamentals》中有这样一段话:

 

 


always uses call by value. That means, the method gets a copy of all parameter values. In particular, the method cannot modify the contents of any parameter variables that are passed to it.

    Many programming languages (in particular, C++ and Pascal) have two methods for parameter passing: call by value and call by reference. Some programmers (and unfortunately even some book authors) claim that the Java programming language uses call by reference for objects. However, that is false. Because this is such a common misunderstanding, it is worth examining a counterexample in detail.

    Let's try to write a method that swaps two employee objects:

public static void swap(Employee x, Employee y) // doesn't work

    {

       Employee temp = x;

       x = y;

       y = temp;

    }    If the Java programming language used call by reference for objects, this method would work:

Employee a = new Employee("Alice", . . .);

    Employee b = new Employee("Bob", . . .);

    swap(a, b);

    // does a now refer to Bob, b to Alice?a and b. The x and y parameters of the swap

x and y are abandoned. The original variables a and b

  
  
  
// x refers to Alice, y to Bob

    Employee temp = x;

    x = y;

    y = temp;

    // now x refers to Bob, y to Alice

程序运行结果:

 

 

调用函数(参数是对象)前:10

调用函数(参数是对象)后:20

调用函数(参数是基本类型int)前:10

调用函数(参数是基本类型int)后:10

调用函数(参数是基本类型Integer)前:10

调用函数(参数是基本类型Integer)后:10

调用函数(参数是String)前:ou

调用函数(参数是String)后:ou

调用函数(参数是StringBuffer)前:ouyang

调用函数(参数是StringBuffer)后:ouyangping

调用函数(参数是String[])前:欧

调用函数(参数是String[])后:平

调用函数(参数是int[])前:10

调用函数(参数是int[])后:20  

总结一下

有两种解释方法、本质是一样的。  

1.从指针的角度考虑、不管你传什么都是指针。  

传过来时、在函数中会使用另外一个地址、但是指向的是相同的内容。  

如果你只是修改了地址、而这个地址跟你传进来之前的地址没有任何关系。  

所以不会发生任何变化。但是你修改了指针的内容、你的修改就会发生作用。  

2.从引用来说、你传递的只是引用本身、并不是引用所指的对象。  

你如果只修改引用本身、也不会影响对象的值。  

一旦你通过引用修改了对象的值、那么这个修改会对对象产生影响。