總所周知,java雖然沒有引用的概念,可是java在傳入參數時,實際傳入的參數對象是外部對象的引用,也就是從新生成一個指向外部對象的對象,只不過這兩個對象指向的是同一片內存對象而已 ,咱們舉例來講明參數和引用的關係,咱們假定方法changeString爲
public void changeString(String a ){
a = new String("I am b!" );
System.out.println(a);
}
那麼當以下調用changeString(String a )方法時
String a = new String("I am a!" );
changeString(a);
......
java的作法實際等價於
String a = new String("abc" );
String b = a;
changeString(b);
............
也就是說在被調用方法內部,傳入參數對象和外部對象是不一樣的對象;雖然二者指向的是同一個內存對象,可是很容易將二者的聯繫斷開 ,好比咱們能夠用以下的方法來測試一下
String a = new String("I am a!" );
System.out.println(a);
//調用changeString方法
changeString(a);
System.out.println(a);
結果應該爲
I am a!;
I am b!;
I am a!;
也 就是說外部對象a的值並無改變,這是由於在changeString(String a )方法內部,參數對象a並非外部對象a了(其實你若是把方法改爲public void changeString(String b)這樣更能理解參數對象b和外部對象a是兩個對象了),參數對象a和外部對象a是兩個對象,指向同一個內存對象new String("abc" ),可是在方法內部,當參數對象a被從新賦值時(a = new String("b" ))時,參數對象
a被從新指向一個新的內存對象new String("I am b!" ),這樣參數對象a和外部對象a斷開了關係 ,再沒有任何聯繫了,所以外部對象a的值也不可能有什麼變化。
經過以上說明,你應該對參數和引用有所理解;說到這裏,咱們要注意變量的賦值,當使用"="爲變量賦值時,通常都是爲變量a從新指定一個新的內存對象,所以當用"只讀對象 "作爲參數時,外部對象的值安全的,這些對象和數據包括爲
基本類型,好比int,char
只讀對象,好比String,Integer等
也就是說你不可能經過調用方法來試圖改變原有對象的值,你能經過調用changeValue(int a,int b)來交換a和b的值麼?
若是某些時候你須要在方法內部改變原有對象的值怎麼辦,辦法很簡單,不要爲參數對象指向新的內部對象,並在此基礎上,調用參數對象的方法來改變內存對象,好比,咱們考慮以下方法
public void changeBufferValue(StringBuffer sb){
sb.append("I am b!");
}
以下調用
StringBuffer a = new StringBuffer("I am a!");
System.out.println(a.toString());
changeBufferValue(a);
System.out.println(a.toString());
輸入結果應該爲
I am a!
I am a!I am b!
若是方法寫成
public void changeBufferValue(StringBuffer sb){
sb = new StringBuffer("I am b!");
}
你應該知道結果是什麼了吧!,所以當你指望方法內部能改變傳入變量的值時,慎用"="號爲參數對象從新賦值。java
一、對於原始數據類型,也就是int、 long、char之類的類型,是傳值的,若是你在方法中修改了值,方法調用結束後,那個變量的值沒用改變。
二、對於對象類型,也就是Object的子類,若是你在方法中修改了它的成員的值,那個修改是生效的,方法調用結束後,它的成員是新的值,可是若是你把它指向一個其它的對象,方法調用結束後,原來對它的引用並沒用指向新的對象。
代碼以下:
public class Tester {
public static void main(String[] args) {
int primitive = 2;
changePrimitive(primitive);
//primitive的值依然是2
MyClass myClass = new MyClass();
changeObject(myClass);
//myClass仍然指向的是執行changeObject以前的那個對象
//可是myClass.i等於3了
}安全
public static void changePrimitive(int primitive) {
primitive = 3;
}app
public static void changeObject(MyClass myClass) {
myClass.i = 3;
myClass = new MyClass();
}
}測試
class MyClass {
int i;
}spa
對於遠程調用,不管是什麼類型,調用結束後,傳入的參數和之前沒用任何變化(固然前途是直接調用遠程方法,若是中間通過其它的Proxy類或者 Facade類,不能保證那些類對對象沒用修改)。至因而經過Locale接口進行調用的,我不太清楚是否屬於遠程調用。之後肯定了再來更新。對象