JAVA中的傳遞都是值傳遞嗎?有沒(méi)有引用傳遞呢?
在回答這兩個(gè)問(wèn)題前,讓我們首先來(lái)看一段代碼:
- public class ParamTest {
-
- protected int num = 0;
-
-
- public void change(int i) {
- i = 5;
- }
-
-
- public void change(ParamTest t) {
- ParamTest tmp = new ParamTest();
- tmp.num = 9;
- t = tmp;
- }
-
-
- public void add(int i) {
- i += 10;
- }
-
-
- public void add(ParamTest pt) {
- pt.num += 20;
- }
-
- public static void main(String[] args) {
- ParamTest t = new ParamTest();
-
- System.out.println("參數(shù)--基本類型");
- System.out.println("原有的值:" + t.num);
-
- t.change(t.num);
- System.out.println("賦值之后:" + t.num);
-
- t.change(t);
- System.out.println("運(yùn)算之后:" + t.num);
-
- System.out.println();
-
- t = new ParamTest();
- System.out.println("參數(shù)--引用類型");
- System.out.println("原有的值:" + t.num);
-
- t.add(t.num);
- System.out.println("賦引用后:" + t.num);
-
- t.add(t);
- System.out.println("改屬性后:" + t.num);
- }
- }
public class ParamTest {
// 初始值為0
protected int num = 0;
// 為方法參數(shù)重新賦值
public void change(int i) {
i = 5;
}
// 為方法參數(shù)重新賦值
public void change(ParamTest t) {
ParamTest tmp = new ParamTest();
tmp.num = 9;
t = tmp;
}
// 改變方法參數(shù)的值
public void add(int i) {
i += 10;
}
// 改變方法參數(shù)屬性的值
public void add(ParamTest pt) {
pt.num += 20;
}
public static void main(String[] args) {
ParamTest t = new ParamTest();
System.out.println("參數(shù)--基本類型");
System.out.println("原有的值:" + t.num);
// 為基本類型參數(shù)重新賦值
t.change(t.num);
System.out.println("賦值之后:" + t.num);
// 為引用型參數(shù)重新賦值
t.change(t);
System.out.println("運(yùn)算之后:" + t.num);
System.out.println();
t = new ParamTest();
System.out.println("參數(shù)--引用類型");
System.out.println("原有的值:" + t.num);
// 改變基本類型參數(shù)的值
t.add(t.num);
System.out.println("賦引用后:" + t.num);
// 改變引用類型參數(shù)所指向?qū)ο蟮膶傩灾?
t.add(t);
System.out.println("改屬性后:" + t.num);
}
}
這段代碼的運(yùn)行結(jié)果如下:
- 參數(shù)--基本類型
- 原有的值:0
- 賦值之后:0
- 運(yùn)算之后:0
-
- 參數(shù)--引用類型
- 原有的值:0
- 賦引用后:0
- 改屬性后:20
從上面這個(gè)直觀的結(jié)果中我們很容易得出如下結(jié)論:
- 對(duì)于基本類型,在方法體內(nèi)對(duì)方法參數(shù)進(jìn)行重新賦值,并不會(huì)改變?cè)凶兞康闹怠?/li>
- 對(duì)于引用類型,在方法體內(nèi)對(duì)方法參數(shù)進(jìn)行重新賦予引用,并不會(huì)改變?cè)凶兞克钟械囊谩?/li>
- 方法體內(nèi)對(duì)參數(shù)進(jìn)行運(yùn)算,不影響原有變量的值。
- 方法體內(nèi)對(duì)參數(shù)所指向?qū)ο蟮膶傩赃M(jìn)行運(yùn)算,將改變?cè)凶兞克赶驅(qū)ο蟮膶傩灾怠?/li>
上面總結(jié)出來(lái)的不過(guò)是我們所看到的表面現(xiàn)象。那么,為什么會(huì)出現(xiàn)這樣的現(xiàn)象呢?這就要說(shuō)到值傳遞和引用傳遞的概念了。這個(gè)問(wèn)題向來(lái)是頗有爭(zhēng)議的。
大家都知道,在JAVA中變量有以下兩種:
- 基本類型變量,包括char、byte、short、int、long、float、double、boolean。
- 引用類型變量,包括類、接口、數(shù)組(基本類型數(shù)組和對(duì)象數(shù)組)。
當(dāng)基本類型的變量被當(dāng)作參數(shù)傳遞給方法時(shí),JAVA虛擬機(jī)所做的工作是把這個(gè)值拷貝了一份,然后把拷貝后的值傳遞到了方法的內(nèi)部。因此在上面的例子中,我們回頭來(lái)看看這個(gè)方法:
-
- public void change(int i) {
- i = 5;
- }
// 為方法參數(shù)重新賦值
public void change(int i) {
i = 5;
}
在這個(gè)方法被調(diào)用時(shí),變量i和ParamTest型對(duì)象t的屬性num具有相同的值,卻是兩個(gè)不同變量。變量i是由JAVA虛擬機(jī)創(chuàng)建的作用域在
change(int i)方法內(nèi)的局部變量,在這個(gè)方法執(zhí)行完畢后,它的生命周期就結(jié)束了。在JAVA虛擬機(jī)中,它們是以類似如下的方式存儲(chǔ)的:
很明顯,在基本類型被作為參數(shù)傳遞給方式時(shí),是值傳遞,在整個(gè)過(guò)程中根本沒(méi)有牽扯到引用這個(gè)概念。這也是大家所公認(rèn)的。對(duì)于布爾型變量當(dāng)然也是如此,請(qǐng)看下面的例子:
- public class BooleanTest {
-
- boolean bool = true;
-
-
- public void change(boolean b) {
- b = false;
- }
-
-
- public void calculate(boolean b) {
- b = b && false;
-
- System.out.println("b運(yùn)算后的值:" + b);
- }
-
- public static void main(String[] args) {
- BooleanTest t = new BooleanTest();
-
- System.out.println("參數(shù)--布爾型");
- System.out.println("原有的值:" + t.bool);
-
- t.change(t.bool);
- System.out.println("賦值之后:" + t.bool);
-
-
- t.calculate(t.bool);
- System.out.println("運(yùn)算之后:" + t.bool);
- }
- }
public class BooleanTest {
// 布爾型值
boolean bool = true;
// 為布爾型參數(shù)重新賦值
public void change(boolean b) {
b = false;
}
// 對(duì)布爾型參數(shù)進(jìn)行運(yùn)算
public void calculate(boolean b) {
b = b && false;
// 為了方便對(duì)比,將運(yùn)算結(jié)果輸出
System.out.println("b運(yùn)算后的值:" + b);
}
public static void main(String[] args) {
BooleanTest t = new BooleanTest();
System.out.println("參數(shù)--布爾型");
System.out.println("原有的值:" + t.bool);
// 為布爾型參數(shù)重新賦值
t.change(t.bool);
System.out.println("賦值之后:" + t.bool);
// 改變布爾型參數(shù)的值
t.calculate(t.bool);
System.out.println("運(yùn)算之后:" + t.bool);
}
}
輸出結(jié)果如下:
- 參數(shù)--布爾型
- 原有的值:true
- 賦值之后:true
- b運(yùn)算后的值:false
- 運(yùn)算之后:true
那么當(dāng)引用型變量被當(dāng)作參數(shù)傳遞給方法時(shí)JAVA虛擬機(jī)又是怎樣處理的呢?同樣,它會(huì)拷貝一份這個(gè)變量所持有的引用,然后把它傳遞給JAVA虛擬機(jī)為方法
創(chuàng)建的局部變量,從而這兩個(gè)變量指向了同一個(gè)對(duì)象。在篇首所舉的示例中,ParamTest類型變量t和局部變量pt在JAVA虛擬機(jī)中是以如下的方式存
儲(chǔ)的:
有一種說(shuō)法是當(dāng)一個(gè)對(duì)象或引用類型變量被當(dāng)作參數(shù)傳遞時(shí),也是值傳遞,這個(gè)值就是對(duì)象的引用,因此JAVA中只有值傳遞,沒(méi)有引用傳遞。還有一種說(shuō)法是引
用可以看作是對(duì)象的別名,當(dāng)對(duì)象被當(dāng)作參數(shù)傳遞給方法時(shí),傳遞的是對(duì)象的引用,因此是引用傳遞。這兩種觀點(diǎn)各有支持者,但是前一種觀點(diǎn)被絕大多數(shù)人所接
受,其中有《Core Java》一書(shū)的作者,以及JAVA的創(chuàng)造者James Gosling,而《Thinking in
Java》一書(shū)的作者Bruce Eckel則站在了中立的立場(chǎng)上。
我個(gè)人認(rèn)為值傳遞中的值指的是基本類型的數(shù)值,即使對(duì)于布爾型,雖然它的表現(xiàn)形式為true和false,但是在棧中,它仍然是以數(shù)值形式保存的,即0表
示false,其它數(shù)值表示true。而引用是我們用來(lái)操作對(duì)象的工具,它包含了對(duì)象在堆中保存地址的信息。即使在被作為參數(shù)傳遞給方法時(shí),實(shí)際上傳遞的
是它的拷貝,但那仍是引用。因此,用引用傳遞來(lái)區(qū)別與值傳遞,概念上更加清晰。
最后我們得出如下的結(jié)論:
- 基本類型和基本類型變量被當(dāng)作參數(shù)傳遞給方法時(shí),是值傳遞。在方法實(shí)體中,無(wú)法給原變量重新賦值,也無(wú)法改變它的值。
- 對(duì)象和引用型變量被當(dāng)作參數(shù)傳遞給方法時(shí),在方法實(shí)體中,無(wú)法給原變量重新賦值,但是可以改變它所指向?qū)ο蟮膶傩?。至于到底它是值傳遞還是引用傳遞,這并不重要,重要的是我們要清楚當(dāng)一個(gè)引用被作為參數(shù)傳遞給一個(gè)方法時(shí),在這個(gè)方法體內(nèi)會(huì)發(fā)生什么。
什么叫引用?只因?yàn)檫@個(gè)變量的值和其它的不一樣.
首先理解:都是變量
int i;
ArrayList b;
i和b都是變量.
但i是基本變量,也叫原始變量.
其它的就叫引用變量,因?yàn)樗闹凳且粋€(gè)內(nèi)存地址值.引用對(duì)象的.但記住:它們都是有一個(gè)值的!i是一個(gè)數(shù)字,而b是一個(gè)內(nèi)存地址值(簡(jiǎn)單的說(shuō)是一個(gè)十六進(jìn)
制的值).除了基本變量之外的變量都是引用變量.Vector a;這里的a也是一個(gè)變量.它也是有值的,它的值是一個(gè)十六進(jìn)制的值.
變量的賦值:
int i=10;
int j=i;
//這里把i的值10給了j,所以j的值也是10
ArrayList b=new ArrayList();
ArrayList c=b;
//首先,b是一個(gè)引用變量,它的"值":是一個(gè)內(nèi)存地址值!!! new
ArrayList()要分配一段內(nèi)存保存它們,怎么樣找到這段內(nèi)存?那就是通過(guò)b里的值了.b的值就是new
ArrayList()所占內(nèi)存的首地址.然后c也是一個(gè)引用變量,它的值(地址值)和b是一樣的.也就是new
ArrayList()所占內(nèi)存的首地址.所以當(dāng)通過(guò)b或者c進(jìn)行操作時(shí),它們都是操作同一個(gè)對(duì)象的.
在方法調(diào)用的時(shí)候,方法的參數(shù)實(shí)際也就是一個(gè)變量.如果是基本類型變量的時(shí)候,假設(shè)有方法method(int aa);
int j=10;
method(j);
這里邊,int aa實(shí)際也是定義了一個(gè)變量,調(diào)用的時(shí)候把j的值:10也給了aa.所以aa也是10,改變了aa的值并不會(huì)改變j的值.
如果是引用變量的時(shí)候,假設(shè)有方法methodA(ArrayList aa);
ArrayList b = new ArrayList();
methodA(b);
//方法定義了變量aa,調(diào)用的時(shí)候把b的值(地址值!!!!!)給了aa,所以aa與b有一樣的值(地址值!!!!),在方法里通過(guò)aa去操作的時(shí)候,b所引用的對(duì)象也就被改變了,因?yàn)樗鼈円猛粋€(gè)對(duì)象.
紙 a = new 銀行帳戶();//開(kāi)一個(gè)銀行帳戶,返回一個(gè)卡號(hào)給你,寫在你的紙a里邊.
用一張紙(引用變量),把你的銀行卡號(hào)寫在上邊,然后調(diào)用我的時(shí)候,我用另外一張紙(引用變量---方法的形數(shù)),把你的號(hào)碼抄過(guò)來(lái).然后我通過(guò)這個(gè)卡號(hào),去到銀行找到你的帳號(hào),給你存點(diǎn)錢.
然后你用你的紙(引用變量)上的卡號(hào) <沒(méi)變,還是那個(gè)卡號(hào)>再去查詢銀行帳號(hào)的時(shí)候就會(huì)發(fā)現(xiàn)了多了一些錢了.....
說(shuō)說(shuō)我對(duì)值傳遞和引用傳遞的看法:
首先我認(rèn)為,大家對(duì)Java傳遞參數(shù)的行為是清楚的,這個(gè)爭(zhēng)論只是一個(gè)語(yǔ)義上的爭(zhēng)論。
也就是我們是否需要區(qū)分值傳遞和應(yīng)用傳遞呢?或者說(shuō)這樣的區(qū)分有沒(méi)有意義?是否合理?
博主認(rèn)為存在引用傳遞的關(guān)鍵點(diǎn)在于,傳遞的對(duì)象地址值,本質(zhì)上它是一個(gè)引用,無(wú)論它是否被copy過(guò)。
認(rèn)為只有值傳遞的關(guān)鍵點(diǎn)在于,傳遞的對(duì)象地址值,它是一個(gè)值的copy,這個(gè)值代表的意義無(wú)所謂。
引用是c++里的概念,由于java跟c++是有一定關(guān)系的,這里把引用遷移過(guò)來(lái),如果合理未嘗不可。
c++中關(guān)于引用的解釋一般喜歡說(shuō)是看作“別名”,我查了幾本書(shū),大部分提到引用并不會(huì)分配內(nèi)存空間,也有一本書(shū)提到,某些編譯器會(huì)分配存儲(chǔ)空間來(lái)存儲(chǔ)被引用對(duì)象的地址。
那么還是回到語(yǔ)義上來(lái),c++里的這個(gè)引用,語(yǔ)義上是“別名”的意思,我的理解是,一組指向同一個(gè)對(duì)象的別名應(yīng)該只存儲(chǔ)一份內(nèi)存地址。當(dāng)然具體實(shí)現(xiàn)可能會(huì)
把引用當(dāng)做一個(gè)不可變的指針來(lái)處理(每個(gè)別名都存儲(chǔ)自己的對(duì)象地址)。但是請(qǐng)注意,我們應(yīng)該關(guān)注于它的語(yǔ)義,即:它沒(méi)有任何值的copy,即使是一個(gè)地
址,只是另外一個(gè)名字而已。
但是java里面沒(méi)有這樣的概念,所有的地址傳遞其行為是值的傳遞方式,語(yǔ)義上統(tǒng)一成值傳遞更為清晰,我們只需要考慮這個(gè)值具體是什么,無(wú)非兩種,要么是基本類型值,要么是個(gè)地址。
所以我認(rèn)為這個(gè)“引用”的概念放到j(luò)ava中并不合適。只有值傳遞的說(shuō)法更合理。
Linux 發(fā)展到今天,可用的軟件已經(jīng)非常多了。這樣自然會(huì)有一些軟件的功能大致上相同。例如,同樣是編輯器,就有
nvi、vim、emacs、nano,而且我說(shuō)的這些還只是一部分。大多數(shù)情況下,這樣的功能相似的軟件都是同時(shí)安裝在系統(tǒng)里的,可以用它們的名稱來(lái)執(zhí)
行。例如,要執(zhí)行 vim,只要在終端下輸入 vim
并按回車就可以了。不過(guò),有些情況下我們需要用一個(gè)相對(duì)固定的命令調(diào)用這些程序中的一個(gè)。例如,當(dāng)我們寫一個(gè)腳本程序時(shí),只要寫下
editor,而不希望要為“編輯器是哪個(gè)”而操心。Debian 提供了一種機(jī)制來(lái)解決這個(gè)問(wèn)題,而 update-alternatives
就是用來(lái)實(shí)現(xiàn)這種機(jī)制的。
在說(shuō)明 update-alternatives 的詳細(xì)內(nèi)容之間,先讓我們看看系統(tǒng)中已有的例子。打開(kāi)終端,執(zhí)行下面的命令:
herbert@natsu:~$ ls -l /usr/bin/editor
lrwxrwxrwx 1 root root 24 2004-09-26 08:48 /usr/bin/editor -> /etc/alternatives/editor
herbert@natsu:~$ ls -l /etc/alternatives/editor
lrwxrwxrwx 1 root root 12 2004-10-27 16:24 /etc/alternatives/editor -> /usr/bin/vim
herbert@natsu:~$
我
們看到,editor 這個(gè)可執(zhí)行命令實(shí)際上是個(gè)符號(hào)鏈接,它指向 /etc/alternatives/editor;而
/etc/alternatives/editor 也是個(gè)符號(hào)鏈接,它指向 /usr/bin/vim。這樣,當(dāng)我輸入 editor
并回車時(shí),將執(zhí)行 vim。之所以要在 /usr/bin 和 /etc/alternatives
中費(fèi)心建立這樣兩個(gè)鏈接,就是要實(shí)現(xiàn)上面說(shuō)到的特性:方便腳本
程序的編寫和系統(tǒng)的管理。
下面我們就來(lái)看看 update-alternatives 的功能。當(dāng)然,如果你覺(jué)得我說(shuō)得不詳細(xì),可以看看這個(gè)命令的 manpage:UPDATE-ALTERNATIVES(8)。
首先要介紹的參數(shù)是 --display。它使我們可以看到一個(gè)命令的所有可選命令。執(zhí)行
natsu:/home/herbert# update-alternatives --display editor
editor - status is auto.
link currently points to /usr/bin/vim
/bin/ed - priority -100
slave editor.1.gz: /usr/share/man/man1/ed.1.gz
/usr/bin/nvi - priority 19
slave editor.1.gz: /usr/share/man/man1/nvi.1.gz
/bin/nano - priority 40
slave editor.1.gz: /usr/share/man/man1/nano.1.gz
/usr/bin/vim - priority 120
slave editor.1.gz: /usr/share/man/man1/vim.1.gz
/usr/bin/emacs21 - priority 0
slave editor.1.gz: /usr/share/man/man1/emacs.1emacs21.gz
Current `best' version is /usr/bin/vim.
natsu:/home/herbert#
你可以看到我的機(jī)器上的所有可以用來(lái)被 editor 鏈接的命令。
下面說(shuō)說(shuō) --config。這個(gè)選項(xiàng)使我們可以選擇其中一個(gè)命令:
natsu:/home/herbert# update-alternatives --config editor
There are 5 alternatives which provide `editor'.
Selection Alternative
-----------------------------------------------
1 /bin/ed
2 /usr/bin/nvi
3 /bin/nano
*+ 4 /usr/bin/vim
5 /usr/bin/emacs21
Press enter to keep the default[*], or type selection number: 4
Using `/usr/bin/vim' to provide `editor'.
natsu:/home/herbert#
我并沒(méi)有修改它,因?yàn)槲疫€是比較喜歡 vim 的。當(dāng)然,你可以選擇別的程序。
說(shuō)
到這里我們就要介紹一些概念了。首先,update-alternatives 在一般情況下是由 postinst 和 prerm
這樣的安裝腳本自動(dòng)調(diào)用的,所以一個(gè) alternative 的狀態(tài)有兩種:自動(dòng)和手動(dòng)。每個(gè) alternative
的初始狀態(tài)都是自動(dòng)。如果系統(tǒng)發(fā)現(xiàn)管理員手動(dòng)修改了一個(gè)
alternative,它的狀態(tài)就從自動(dòng)變成了手動(dòng),這樣安裝腳本就不會(huì)更新它了。如果你希望將一個(gè) alternative 變回自動(dòng),只要執(zhí)行
update-alternatives --auto editor
就可以了。你注意到了嗎?我們說(shuō)到了“名字”。該怎樣寫名字呢?這就是我們要介紹的第二個(gè)概念:
general name -- 這是指一系列功能相似的程序的“公用”名字(包括絕對(duì)路徑),比如 /usr/bin/editor。
link -- 這是指一個(gè) alternative 在 /etc/alternative 中的名字,比如 editor。
alternative -- 顧名思義,這是指一個(gè)可選的程序所在的路徑(包括絕對(duì)路徑),比如 /usr/bin/vim。
--
auto,--display 和 --config 跟的都是
link。我們要說(shuō)的第三個(gè)概念是優(yōu)先級(jí)。這個(gè)比較簡(jiǎn)單,當(dāng)然優(yōu)先級(jí)越高的程序越好啦(在大多數(shù)情況下,我不想爭(zhēng)論)最后一個(gè)概念是主和從的
alternative。想想看,你將 /usr/bin/editor 鏈接到了 vim,可是當(dāng)你執(zhí)行 man editor 時(shí)看到的卻是
emacs 的 manpage,你會(huì)做何感想呢?這就引出了主和從 alternative 的概念了:當(dāng)更新主的 alternative
時(shí),從的 alternative 也會(huì)被更新。
說(shuō)完這四個(gè)重要的概念后,我們介紹另外兩個(gè)選項(xiàng)。至于其他的。。。。我相信你會(huì)去看手冊(cè)頁(yè)的,對(duì)嗎?
第一個(gè)是 --install。它的格式是:
update-alternatives --install gen link alt pri [--slave sgen slink salt] ...
gen,
link,alt,pri 分別是我們上面說(shuō)過(guò)的。如果需要從的 alternative,你可以用 --slave
加在后面。如果你在向一個(gè)已經(jīng)存在的 alternative 組中添加新的 alternatives,該命令會(huì)把這些 alternatives
加入到這個(gè)已經(jīng)存在的 alternative 組的
列表中,并用新的可選命令作為新的命令;否則,將會(huì)建立一個(gè)新的自動(dòng)的 alternative 組。
嗚呼!我加入了一個(gè)錯(cuò)誤的 alternative。我不想要這個(gè) alternative 了。在這種情況 下,可以執(zhí)行下面的命令:
update-alternatives --remove name path
name
是一個(gè)在 /etc/alternatives 中的名字,也就是上面的 link,而 path
是希望刪除的可選程序名的絕對(duì)路徑名(放心,這樣只是從列表中刪除了這個(gè)程序,并不會(huì)真的從硬盤上刪除程序的可執(zhí)行文件)。如果從一個(gè)
alternative 組中刪除了一個(gè)正在被鏈接的程序并且這個(gè)組仍然沒(méi)有變成空的,update-alternatives
會(huì)自動(dòng)用一個(gè)具有其他優(yōu)先級(jí)的可選程序代替原來(lái)的程序。如果這個(gè)組變成空的了,那么連這個(gè) alternative
組都會(huì)被移除。如果刪除的程序沒(méi)有被鏈接,則只有有關(guān)這個(gè)程序的信息會(huì)被移除。
說(shuō)個(gè)例子吧。我下載了 Eclipse,并且安裝了
gcj 和 gij。可是我發(fā)現(xiàn) GNU 的 java 工具還不足以運(yùn)行 Eclipse。我只好到 Sun 公司的網(wǎng)頁(yè)上下載了它的 java
工具 jdk。因?yàn)槭亲约喊惭b的,我將它們安裝在 /usr/local 上,以便將來(lái)重新安裝 Linux
系統(tǒng)時(shí)這些程序仍然可以使用。于是我要做的就是用這個(gè) jdk 中的 java 和 javac 來(lái)代替系統(tǒng)原來(lái)的。執(zhí)行
natsu:/home/herbert# update-alternatives --display java
java - status is auto.
link currently points to /usr/local/j2sdk1.4.2_06/bin/java
/usr/bin/gij-wrapper-3.3 - priority 33
slave java.1.gz: /usr/share/man/man1/gij-wrapper-3.3.1.gz
/usr/local/j2sdk1.4.2_06/bin/java - priority 100
slave java.1.gz: /usr/local/j2sdk1.4.2_06/man/man1/java.1
Current `best' version is /usr/local/j2sdk1.4.2_06/bin/java.
natsu:/home/herbert# update-alternatives --display javac
javac - status is auto.
link currently points to /usr/local/j2sdk1.4.2_06/bin/javac
/usr/bin/gcj-wrapper-3.3 - priority 33
slave javah: /usr/bin/gcjh-wrapper-3.3
slave javac.1.gz: /usr/share/man/man1/gcj-wrapper-3.3.1.gz
slave javah.1.gz: /usr/share/man/man1/gcjh-wrapper-3.3.1.gz
/usr/bin/gcj-wrapper-3.4 - priority 33
slave javah: /usr/bin/gcjh-wrapper-3.4
slave javac.1.gz: /usr/share/man/man1/gcj-wrapper-3.4.1.gz
slave javah.1.gz: /usr/share/man/man1/gcjh-wrapper-3.4.1.gz
/usr/local/j2sdk1.4.2_06/bin/javac - priority 100
slave javah: /usr/local/j2sdk1.4.2_06/bin/javah
slave javac.1.gz: /usr/local/j2sdk1.4.2_06/man/man1/javac.1
slave javah.1.gz: /usr/local/j2sdk1.4.2_06/man/man1/javah.1
Current `best' version is /usr/local/j2sdk1.4.2_06/bin/javac.
natsu:/home/herbert#
(你看到的是我更新以后的)就可以得到關(guān)于要更新哪些 alternatives 的信息。我是這么更新的:
update-alternatives
--install /usr/bin/javac javac /usr/local/j2sdk1.4.2_06/bin/javac 100
--slave /usr/bin/javah javah /usr/local/j2sdk1.4.2_06/bin/javah --slave
/usr/share/man/man1/javac.1.gz javac.1.gz
/usr/local/j2sdk1.4.2_06/man/man1/javac.1 --slave
/usr/share/man/man1/javah.1.gz javah.1.gz
/usr/local/j2sdk1.4.2_06/man/man1/javah.1
update-alternatives
--install /usr/bin/java java /usr/local/j2sdk1.4.2_06/bin/java 100
--slave /usr/share/man/man1/java.1.gz java.1.gz
/usr/local/j2sdk1.4.2_06/man/man1/java.1