欢迎转载,转载请声明出处!
  -----------------------------------------
  前言:
 java语言中,參数的传递仅仅有一种机制。那就是值传递。  举例:
 以下将通过几个样例来说明java中的參数传递机制,这些样例基本涵盖了全部參数传递的情况。
  1.基本数据类型:
 public static void testBase(int i)   {i = 2;}測试:
int i = 10;
System.out.println(i);//10
testBase(i);
System.out.println(i);  //10结果当然非常显然都是10。由于基本数据类型传递的是值的一份拷贝(副本),对副本操作不影响原始值。
 2.对象:
      2.1.对參数又一次赋值:
 public static void testObj(Object o)
{o = new Object();
}測试:
Object o = new Object();
System.out.println(o);// java.lang.Object@1ff61bcf  
testObj(o);
System.out.println(o);//java.lang.Object@1ff61bcf方法中的參数仅仅是原始对象的一份拷贝,更准确的讲是地址的一份拷贝,故而对其进行又一次赋值并不会影响原始对象。
   2.2.改变对象内部数据:
 public class S
{private Object o = new Object();private int i = 2;public Object getO(){return o;}public void setO(Object o){this.o = o;}public int getI(){return i;}public void setI(int i){this.i = i;}
}
public static void testA(S s)
{s.setI(100);s.setO(new Object());
}測试:
S s = new S();
System.out.println(s.getI()+","+s.getO());// 2,java.lang.Object@11b75be2  
testA(s);
System.out.println(s.getI()+","+s.getO());//100,java.lang.Object@1cf15b84由于对象作为參数传递的是对象的引用地址(注意,这是值传递)。故參数所指的对象和原始引用所指的对象都是堆中的同一个对象,故在測试方法中改动对象内容会改变对象的数据。
试试自己分析这个样例(跟上面是一样的):
 package test;
public class A
{int t = 6;Object obj = new Object();public static void main(String[] args){A a = new A();  a.func(a.t,a.obj);//问t和obj的值是否变化。答案:不变化}public void func(int t,Object obj){t = 7;obj = null;}
} 3.数组:
      3.1.对參数又一次赋值:
   public static void testArr(int[] arr){arr = null;}int[] arr = {1,2};
System.out.println(arr[0]);//1
testArr(arr);
System.out.println(arr[0]);  //1 传递机制跟对象一样,也是传递的对象地址,故而也不改变原始值。
       3.2.改变參数内部数据:
  public static void testArr(int[] arr){arr[0] = 100;}int[] arr = {1,2};
System.out.println(arr[0]);//1
testArr(arr);
System.out.println(arr[0]);//100 结果无须解释了吧。
  4.基本数据类型的包装类型:
      事实上跟基本类型是一样的。
 public static void testWrapper(Float f)
{f = 100.0f;
}Float f = 12.0f;
System.out.println(f);//12.0
testWrapper(f);
System.out.println(f);//12.0 5.【重点】字符串:
  字符串作为參数的情形比較特殊。
      5.1.对參数又一次赋值:
 public static void testStr1(String str)
{str = "testOK";
} String str = "test";       System.out.println(str);//testtestStr1(str);System.out.println(str);//test5.2.对參数运行替换、连接等操作:
 public static void testStr2(String str)   {str = str.concat("OK");str = str.toUpperCase();}String str = "test";
System.out.println(str);//test
testStr2(str);
System.out.println(str);//test 也是对str的又一次赋值。不改变原始串.
      5.3.对參数运行+的操作
 public static void testStr3(String str){str += "OK";}String str = "test";
System.out.println(str);//test
testStr3(str);
System.out.println(str);//teststr += "OK";
str = new StringBuilder(str).append("OK").toString();//编译时会还原成这样 显然也是对副本又一次赋值。并不影响原始的对象。
  使用javap -c反编译一下会非常直观:
  6.StringBuffer或StringBuilder作为參数:
      6.1又一次赋值
 public static void testStringBuilder(StringBuilder sb)
{sb = new StringBuilder("testOK");
}StringBuilder sb = new StringBuilder("test");
System.out.println(sb.toString());//test
testStringBuilder(sb);
System.out.println(sb.toString());//testpublic static void testStringBuilder(StringBuilder sb)
{sb.append("OK");
}StringBuilder sb = new StringBuilder("test");
System.out.println(sb.toString());//test
testStringBuilder(sb);
System.out.println(sb.toString());//testOK 7.交换问题
      经过上面的样例。相信对java參数传递机制比較清楚了,所以请不要再写这种代码了:
 public static void swap(Integer a, Integer b)
{Integer temp = a;a = b;b = temp;
}总结:
 1.假设參数是基本数据类型(包含相应的包装类型)。那么參数传递时仅仅是原始值的一份拷贝或者叫副本,对副本操作并不影响原始值;
  2.假设參数是对象(引用类型),那么參数传递时传递的是对象的地址的一份拷贝,所以对对象内部属性的操作会改变原始对象对应值,可是对该參数进行又一次赋值并不会影响原始对象;
  3.String类型作为參数进行传递时,传递的也是地址。可是String类比較特殊,对參数进行concat,replace,’+‘等操作时不影响原始的串。对參数又一次赋值当然也不影响原始字符串。
  4.数组类型作为參数跟传递对象时一样的。