?? 關于[開心就好]提出的“如何殺死一只雞”的問題的討論意見.txt
字號:
作者:sonymusic
email: sonymusic@china.com
日期:7/10/2001 12:59:38 AM
[H3][#ff0000]關于[開心就好]提出的“如何殺死一只雞”的問題的討論意見 [/#][/H3]
[B]他的問題如下:[/B]
一個方法:kill()
希望傳遞一個雞的參數,然后在kill方法內將這只雞殺死,并希望在方法外,這只雞也是“真”的被殺死了。
他給出的代碼如下,并依據這段代碼得出結論:JAVA不是好廚師,殺一只雞都殺不死。先看代碼吧。
public class test{
public static void main(String[] args){
int i=0;
int j=1;
Chicken chicken=new Chicken();
int k=chicken.killChicken(i,j);
System.out.println(i+"\n"+k);
}
}
class Chicken{
public int killChicken(int i,int j){
i++;
return i+j;
}
};
//the Result is "0,2",it's why?
[B]這段代碼有什么問題呢?[/B]
嗯,相當的多,就找最嚴重的吧,其實也是他為什么得不出正確答案的原因。
開心就好提出的問題是如何殺雞,可是從他的代碼所表示的意思來看,其實是先“造”了一只雞,然后用這只雞去殺兩個數字。這能殺得死嗎?
這里至少犯了兩個錯誤:1,這段代碼沒有體現出一點OO的思想,既然是“殺雞”,怎么能“造”一只雞,來殺數字呢?2,這段代碼理解錯了JAVA中參數傳遞的概念。
OK,再來看看我根據羅亭的代碼所改寫的代碼吧。
public class Chicken {
private boolean IsLiving = true;//雞還活嗎?
/** 判斷雞是否還活著 */
public boolean isLiving(){
return this.IsLiving;
}
/** 雞被捅了一刀 */
public void killed(){
this.IsLiving = false;
}
}
public class Killer {
/** 準備吃雞肉,如果沒殺死,當然是吃不到手了 ^o^ */
public void killChicken(Chicken _Chicken){
_Chicken.killed();
}
public static void main(String[] args){
Chicken chicken=new Chicken();//這個時候還是活著的
System.out.println("活著么?"+chicken.isLiving());
Killer killer=new Killer();//弄把刀來
killer.killChicken(chicken);//我殺殺殺!
System.out.println("活著么?"+chicken.isLiving());//死啦!
}
}
[B]運行結果如下:[/B]
活著么?true
活著么?false
[B]原因:[/B]
在JAVA中,如果方法的參數是基礎類型,如int,float等,那么是以傳值的方式傳遞參數的(即,在方法內部改變參數,不會影響方法外的值)。這就是開心所做的測試不成功的原因。
如果方法的參數是對象的話,就是以傳引用的方式傳遞參數(即,在方法內部,你可以改變參數的值,方法返回后參數的值的改變可以被反映出來),這就是殺雞的原理。
[B]解決:[/B]
那么,JAVA中如何應對另外兩種情況(即,以引用方式來傳基礎類型,和傳值方式來傳遞對象)呢?
第一種情況中,需要構造一個對象,
public class IntegerImpl{
int value;
public IntegerImpl(int newValue){
this.value=newValue;
}
public int getInt(){
return value;
}
public void setInt(int newValue){
value=newValue;
}
}
在方法調用的時候,使用這樣的類來作為參數傳遞即可。注意,java.lang.Integer類并不適用。 第二種情況中,需要在方法一開始,先復制一個參數的復本,以后的操作只對復本進行。如下:
public killChicken(Chicken oldChicken){
chicken=oldChicken.clone();
kill(chicken);
//方法返回后,這只雞還是活的。
}
[B]結論:[/B]
不管是需要傳值還是傳引用,在JAVA中當然都是可以做到的。雖然要將int等類型作為引用傳遞比較麻煩,不過這種情況并不是很多見。
而在.net中,ref關鍵字的作用看似很大,其實并沒什么用處,如boss_ch所說,只是MS公司為了保持與C++的某些相似性而設置的。尤其是在傳遞對象的時候,當傳遞一只雞給一個方法去“殺死”的時候,難道默認的居然是先造另一只雞去殺么?不符合人的常規思維。 最后,以羅亭的話來結尾,
[#330033][I]你看你的代碼中殺的是什么?
眼中無雞,豈能殺得了雞?[/I][/#]
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -