一:
1 :如果參數是基礎資料型別 (Elementary Data Type)(四類八種:byte,short,int,long,double,float,double,
boolean,char),那麼傳的是變數的值,例如: int a= 10; 那麼傳過去的就是10!
例子:
package qqwwffg.pass_method_paramater;
public class PrimitiveType {
public void change(int a) {
a = 3;
}
public static void main(String[] args) {
int a = 1;
PrimitiveType test = new PrimitiveType();
test.change(a);
System.out.println(a); // 1 ,而不是3
}
}
change 方法在被調用的時候,在記憶體中也分配一個空間來儲存,存的是傳過來的值,即3 .而當方法結束時,這塊記憶體就等記憶體回收了,而在main 方法中,它列印的a 的值是在調用main方法時分配的記憶體空間,他們倆之間沒有任何關係,所以列印的還是1.
2 : 如果參數是引用資料類型(類,數組,介面),那麼傳的是也是變數的值,例如: Point param = new Point(); 那麼傳過去的是point 這個變數的值 ,而不是說Point 這個對象!而point 這個變數的值,其實就是Point 對象在記憶體中的地址(也叫引用)!
例子:
public class ReferenceType {
public void changePoint(Point point) {
point.x = 5;
point.y = 6;
}
public void changeReference(Point point) {
point = null;
}
public void testPassByStirng(String param) {
param = "newValue";
}
public static void main(String[] args) {
int a = 1;
Point point = new Point(1, 2);
ReferenceType test = new ReferenceType();
test.changePoint(point);
System.out.println(point.x); // 5 而不是 1
System.out.println(point.y); // 6 而不是 2
test.changeReference(point); // 調用這個後,下面是否會報null 指標呢?
int x = point.x; // 不會
System.out.println("x 的值是 " + x );
String param = "value";
test.testPassByStirng(param);
System.out.println(param); // 是value ,而不是 newValue
}
}
class Point {
int x;
int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
在java 中,訪問對象是通過指向對象的引用來操作的,而一個對象可以被多個引用所指向,無論其中哪個引用對這個對象的內容進行修改,它都會影響到另外一個引用,雖然引用有多個,但對象卻只有一個!
changePoint 方法被調用時,你把main 方法中的Point 對象的引用point 傳給了changePoint的參數
point,此時,這個point 引用也指向了main 方法中的Point 對象(new 出來的),而你在這個方法中,
用point 這個引用對Point 對象(new 出來的)的內容進行了修改(point.x = 5;point.y = 6;),因為它們指向的是同一個Point 對象(new 出來的),所以,當方法執行完後,這個修改會反映到這
個對象上,而此時,你再列印出Point 對象的x,y 的值,都是被改變後的值! 即不再是1和2,而是5與6 .
小結:
在java 中,方法參數的傳遞永遠都是傳值,而這個值,對於基礎資料型別 (Elementary Data Type),值 就是你賦給變數的那個值,而對於引用資料類型,這個值是對象的引用,而不是這個對象本身.
二: 在java 中,通過方法的調用,只能改變對象的內容,而不能改變對象的引用.
如 上面的方法public void changeReference(Point point) {
point = null;
}
point = null ,這句話是把你在調用changeReference方法時,本來point 這個引用與你在main 方法中
的那個point 引用指向的是同一個對象,而當你調用point = null 時,它就不再指向原來的Point 對象
了,此時,它只是改變它自身的指向,並沒有對main 方法中的point 引用進行修改,main 中的point 引用
還是指向main 中的Point 對象!所以,你在main 方法中調用 point.x; 是不會發生null 指標異常的.
也就是說:在方法中,你把引用 所對應的對象的內容給改變了,它是會反應到對象上的
,這時,你再取對象的內容時,已經是你改變過了的!而無論你把傳過去的引用如何
改(point = null),該引用永遠指向它原來 的那個對象!
在這裡說一點的就是:張老師在視頻中說到當String 做為參數傳遞的時候,是由於String對象本身是不變對象所決定的! 上面的testPassByStirng 方法.
而我自己的想法是:String 類型,它是不變對象,但它符合二:
當它作參數傳過去時,如果對引用操作如: paramString = "改變原來的值";
這個所做的是: "改變原來的值" 其實就是String類的一個匿名對象,所以,你這樣是在
方法中,重新構造一個String 對象出來,然後這個對象的引用賦給paramString ,此時,
把paramString 這個引用 給改變了,但傳過來的引用並沒有被改變!