1.函數(shù)參數(shù)傳遞方式
雖然java通過引用操作對象腮敌,所有的對象變量都是引用阱当,然而,java不能通過引用
傳遞方法參數(shù)糜工,它通過值傳遞
弊添。基本類型傳遞的是值的副本捌木,引用類型傳遞的是引用的副本油坝。如果函數(shù)內(nèi)修改了該參數(shù),僅改變副本刨裆,而原始值保持不變
澈圈。
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
//交換
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
//輸出結(jié)果
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
即使該方法是值傳遞,但它還是成功的輸出了pnt1的值帆啃。然而瞬女,pnt1和pnt2的卻沒有交換成功。這兩個參數(shù)引用
傳遞給方法時事實上是把原始引用復(fù)制了一份努潘。函數(shù)方法內(nèi)的交換只是復(fù)制引用地址的交換诽偷,原始引用并沒有發(fā)生變化。傳給方法后疯坤,一個對象至少有兩個引用
报慕。在函數(shù)方法里面可以修改對象的數(shù)據(jù)
。
2.實現(xiàn)函數(shù)參數(shù)的“任意化”的手段
可以通過Object和泛型實現(xiàn)參數(shù)的“任意化”压怠,相比較的優(yōu)缺點:
- Object要做顯式的強制類型轉(zhuǎn)換眠冈,而這種轉(zhuǎn)換是要求開發(fā)者對實際參數(shù)類型可以預(yù)知的情況下進行的。而泛型的好處是在編譯的時候檢查類型安全菌瘫,并且所有的強制轉(zhuǎn)換都是自動和隱式的蜗顽,提高代碼的重用率玄柠。
- 從安全的角度來看,由程序員自己強制類型轉(zhuǎn)換诫舅,出錯率很高羽利。采用范型后由編譯器生成強制類型轉(zhuǎn)換的代碼,降低了出錯率刊懈。JDK1.5以后就有了泛型这弧。
3.動態(tài)參數(shù)
4.函數(shù)方法使用final 修飾參數(shù)的作用。
參數(shù)(如果是引用類型虚汛,引用類型參數(shù)是所指的引用副本)不能被重新賦值匾浪,否則編譯就通不過。是否使用final修飾參數(shù)卷哩,對外部的影響實際效果是一樣的
蛋辈。
如果函數(shù)方法里面使用匿名內(nèi)部類,并且內(nèi)部類中使用該參數(shù)将谊。那么參數(shù)必須用final修飾冷溶。局部內(nèi)部類(包括匿名局部內(nèi)部類和普通內(nèi)部類)中使用局部變量,那么這個局部變量必須使用final修飾
尊浓。如:
public class Outer {
{
//x和y必須用final修飾逞频,否則編譯不通過
final int x=100;
final int y=100;
//內(nèi)部類
class BlockInner{
int z=100;
public int addXYZ(){return x+y+z;}
}
BlockInner bi=new BlockInner();
num=bi.addXYZ();
}
private int num;
}
用final修飾是因為:
(1)對于普通局部變量他的作用域就是該方法內(nèi),當(dāng)方法結(jié)束該局部變量就隨之消失
栋齿;但局部內(nèi)部類可能產(chǎn)生隱式的“閉包”苗胀,閉包將使得局部變量脫離他所在的方法繼續(xù)存在。此時就會出現(xiàn)一種情況瓦堵,就是內(nèi)部類要訪問一個不存在的局部變量
基协。如下面代碼:
//name 必須使用final修飾,否則編譯不通過
public void mRun(final String name){
new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name);
}
}.start();
}
//方法myRun已調(diào)用結(jié)束(局部變量已死亡)菇用,但是匿名內(nèi)部類(線程)對象仍然活著,需要使用外部局部變量name澜驮。
(2)上面代碼說明局部類的對象生命期會超過局部變量
,解決這一問題的辦法就是使用final修飾局部變量刨疼,使內(nèi)部類擴大
局部變量的作用域泉唁。其原理通過將final局部變量"復(fù)制"一份, 復(fù)制品直接作為方法內(nèi)部類中的數(shù)據(jù)成員
,方法內(nèi)部類訪問的其實是這個局部變量的復(fù)制品揩慕!而且,由于被final修飾的變量賦值后不能再修改扮休,所以就保證了復(fù)制品與原始變量的一致
迎卤。
注:JDK1.8版本以后,可以不用final修飾玷坠,都是隱式處理的
蜗搔。但是本質(zhì)上該變量還是final的劲藐。這該版本的新特性。