top
Loading...
Java二進制兼容性原理
天極IT資訊短信服務 電腦小技巧
資費:包月5元
手機:
介紹:細處著手,巧處用功。高手和菜鳥之間的差別就是:高手什么都知道,菜鳥知道一些。電腦小技巧收集最新奇招高招,讓你輕松踏上高手之路。


一、概述

現在的軟件越來越依賴于不同廠商、作者開發的共享組件,組件管理也變得越來越重要。在這方面,一個極其重要的問題是類的不同版本的二進制兼容性,即一個類改變時,新版的類是否可以直接替換原來的類,卻不至于損壞其他由不同廠商/作者開發的依賴于該類的組件?

Java二進制兼容性概念的主要目標是推動Internet上軟件的廣泛重用,同時它還避免了大多數C++環境面臨的基礎類脆弱性問題——例如,在C++中,對域(數據成員或實例變量)的訪問被編譯成相對于對象起始位置的偏移量,在編譯時就確定,如果類加入了新的域并重新編譯,偏移量隨之改變,原先編譯的使用老版本類的代碼就不能正常執行;虛擬方法調用也存在同樣的問題。

C++環境通常采用重新編譯所有引用了被修改類的代碼來解決問題。在Java中,少量開發環境也采用了同樣的策略,但這種策略存在諸多限制。例如,假設有人開發了一個程序P,P引用了一個外部的庫L1,但P的作者沒有L1的源代碼;L1要用到另一個庫L2。現在L2改變了,但L1無法重新編譯,所以P的開發和更改也受到了限制。

為此,Java引入了二進制兼容的概念——如果對L2的更改是二進制兼容的,那么更改后的L2、原來的L1和現在的P能夠順利連接,不會出現任何錯誤。

首先來看一個簡單的例子。Authorization和Hello類分別來自兩個不同的作者,Authorization提供身份驗證和授權服務,Hello類要調用Authorization類。

package com.author1;

public class Authorization {
public boolean authorized(String userName) {
return true;
}
}


package com.author2;

import com.author1.*;

class Hello {
public static void main(String arg[]) {
Authorization auth = new Authorization();
if(auth.authorized("MyName"))
System.out.println("您已經通過驗證");
else
System.out.println("您未能通過身份驗證");
}
}

現在author1發布了Authorization類的2.0版,Hello類的作者author2希望在不更改原有Hello類的情況下使用新版的Authorization類。2.0版的Authorization要比原來的復雜不少:

package com.author1;

public class Authorization {
public Token authorized(String userName, String pwd) {
return null;
}
private boolean determineAuthorization(String userName, String pwd) {
return true;
}
public boolean authorized(String userName) {
return true;
}
public class Token { }
}

作者author1承諾2.0版的Authorization類與1.0版的類二進制兼容,或者說,2.0版的Authorization類仍舊滿足1.0版的Authorization類與Hello類的約定。顯然,author2編譯Hello類時,無論使用Authorization類的哪一個版本都不會出錯——實際上,如果僅僅是因為Authorization類升級,Hello類根本無需重新編譯,同一個Hello.class可以調用任意一個Authorization.class。

這一特性并非Java獨有。UNIX系統很早就有了共享對象庫(.so文件)的概念,Windows系統也有動態鏈接庫(.dll文件)的概念,只要替換一下文件就可以將一個庫改換為另一個庫。就象Java的二進制兼容特性一樣,名稱的連接是在運行時完成,而不是在代碼的編譯、連接階段完成,而因它也同樣擁有Java二進制兼容性所具有的優點,例如修改代碼時只需重新編譯一個庫,便于對程序的某一部分進行修改。但是,Java的二進制兼容性還有其獨特的優勢:

⑴ Java將二進制兼容性的粒度從整個庫(可能包含數十、數百個類)細化到了單個的類。

⑵ 在C/C++之類的語言中,創建共享庫通常是一種有意識的行為,一個應用軟件一般不會提供很多共享庫,哪些代碼可以共享、哪些代碼不可共享都是預先規劃的結果。但在Java中,二進制兼容變成了一種與生俱來的天然特性。

⑶ 共享對象只針對函數名稱,但Java二進制兼容性考慮到了重載、函數簽名、返回值類型。

⑷ Java提供了更完善的錯誤控制機制,版本不兼容會觸發異常,但可以方便地捕獲和處理。相比之下,在C/C++中,共享庫版本不兼容往往引起嚴重問題。

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗