程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 走上開放之路: .NET 開發人員的 J2EE 基礎(上)

走上開放之路: .NET 開發人員的 J2EE 基礎(上)

編輯:關於JAVA

您是一位正在尋求將 .NET 電子商務應用程序移植到 Java 2 Platform Enterprise Edition(J2EE)的 .NET 開發人員嗎?或者,您是否需要從頭編寫您的第一個 J2EE 應用程序?不管是哪一種情況,本路標圖都是為您准備的。它是專門為想要迅速轉到 J2EE 的 .NET 開發人員准備的,J2EE 是使用 Java 語言開發 Web 和其他類型的分布式應用程序的一個平台無關的開放標准集。我們將向您介紹如何使用 Java 語言來編程和開發 J2EE Web 應用程序。更好的是,我們將把這些信息與您已從編寫 .NET 應用程序的經驗中知道的概念和技術聯系起來。

為何要轉向 J2EE?

如果您不是十分渴望冒險投入一種新的開發環境,可以考慮以下這些 J2EE 好處:

選擇,更多的選擇:由於 J2EE 是一個定義良好的標准集,您在部署自己的代碼時有許多 J2EE 實現可供選擇。只要堅持使用標准 API 和避免廠商專用的擴展,應用程序無需編碼變更就能在各種各樣的 J2EE 實現上運行。

我們是在說選擇嗎?:J2EE 實現在從大型機到 Wintel、UNIX 和 Linux 的各種平台上可用。您可以編寫應用程序一次,然後在各種不同的平台上部署它。

我們不能就安於現狀嗎?:J2EE 包括一個用於訪問許多諸如 CICS、IMS、ERP 和 CRM 這樣的遺留 EIS 系統的標准 API。它還包括 Web 服務支持,因此您可以集成 .NET 系統和支持行業 Web 服務標准的其他系統。J2EE 還包括標准消息 API 支持(Java Message Service,JMS),以及一個用於訪問關系數據庫的 API(Java Database Connectivity,JDBC)。這樣廣泛的選擇允許您集成各種現有的系統,而不會損失您對它們的投資。

機房不再煙霧缭繞:來自世界各地的專家通過 Java Community Process(JCP)開發 J2EE 規范。JCP 發布了初步的規范草案以供公眾評論。即使您不主動參與,也總是會知道哪些未來的規范正在籌備之中。該規范還包括一個參考實現,您可以在決定實現它之前使用它來檢查新技術。

J2EE 簡介

J2EE、即 Java 2 Enterprise Edition,是一個由許多與使用 Java 語言開發分布式應用程序相關的組件組成的規范。您可以使用 J2EE 組件來編寫基於 Web 的應用程序和傳統的客戶機-服務器應用程序,以及使用標准的 API 來連接到諸如關系數據庫等遺留資源。如果您來自 ASP.NET 開發背景, Java Servlets和 JavaServer Pages(JSP)技術就是對您最有用的組件。

Java Servlets

Java Servlets 是作為諸如 IIS 或 Apache Web Server 等 Web 服務器的擴展來運行的 Java 類。Java Servlet 類似於 ISAPI 過濾器,即 ASP.NET HttpHandler 類,或類似於 cgi-bin 程序/腳本。Java Servlet 在客戶端浏覽器直接或間接地調用一個專門配置的 URL 時運行。servlet 能夠訪問 HTTP 請求中的所有信息,並且能夠通過提供返回給客戶端的內容來直接處理該請求。或者,servlet 能夠將客戶端浏覽器重定向到另一個資源。大多數 J2EE Web 應用程序都主要把 servlet 用作 HTML 表單的目標以處理用戶輸入,然後作相應的處理。響應頁面的生成通常委托給 JSP 頁面。

JavaServer Pages 技術

JSP 頁面類似於 ASP.NET 頁面。也就是說,它們也是包含腳本元素的 HTML 頁面,這些腳本在用戶請求該頁面時在服務器上運行。ASP.NET 頁面和 JSP 頁面之間的一個關鍵區別在於,ASP.NET 頁面使用某種 .NET 語言(比如 C# 和 VB.NET)作為腳本語言,而 JSP 頁面使用 Java 語言。典型的 JSP 頁面包含 Java 代碼片斷和 JSP 規范中定義的一些特殊的類 HTML 標簽,它們與標准 HTML 交織在一起以提供靜態和動態內容的組合。Java Servlet 和 JSP 頁面之間的區別在概念上類似於 ASP.NET HttpHandler 類和 ASP.NET 頁面之間的區別。在兩種情況下,前者都是可用於直接或間接地向其他資源發送 HTML 的一段代碼,後者都是一個可以包含嵌入代碼的 HTML 文檔。

Web 服務器和應用服務器

如果熟悉 ASP.NET 頁面,您應該知道運行這些頁面的 ASP.NET 運行庫――它配合 IIS 工作。您還會向 Web 應用程序添加自己的 HttpHandler 類以及托管的和非托管的組件,ASP.NET 運行庫也會調用這些組件。這使得在 IIS 上部署 Web 應用程序很容易。但是它把您限制在 Windows 平台上,即唯一能夠運行 IIS 的平台。J2EE 使用一種不同的方法,因為它的設計目標就是運行在各種不同的操作系統上(包括 Windows)。與嘗試將運行 Java Servlet 和 JSP 頁面的代碼直接嵌入 Web 服務器不同,它使用一個稱為 應用服務器的單獨服務器組件來運行它們。大多數應用服務器(比如 IBM WebSphere Application Server)還有一個單獨的插入組件,用於橋接應用服務器和特定的 Web 服務器。例如,WebSphere Application Server 附帶了針對 IIS 和 Apache Web server 的單獨插件。這樣允許您在運行 J2EE 組件時使用自己選擇的 Web 服務器。

應用服務器作為單獨的可插入服務器組件這種角色帶來了多個優點:

Web 服務器選擇:您不會被限定使用某個 Web 服務器來提供 HTML 頁面服務。您可以繼續使用自己最喜歡的 Web 服務器來用於此目的,並且使用任何應用服務器來處理 Java Servlet 和 JSP 頁面。這種能力在您將 ASP.NET 應用程序移植到 J2EE 時特別有用。您可以繼續運行 IIS 和 ASP.NET 運行庫,並且分階段地移植應用程序。您不需要一下子改寫整個應用程序。

平台選擇:你可以編寫 J2EE 應用程序一次,然後在能夠運行應用服務器的各種不同操作系統上部署它——包括 Windows、AIX 和 Linxu。您不會被限定於某個能夠運行特定 Web 服務器的平台。

應用服務器廠商選擇:由於行業標准規范定義了 Java Servlets 和 JavaServer Pages 技術,您可以編寫 J2EE 應用程序一次,然後在多種應用服務器環境中部署它,比如 WebSphere Express 或 Apache Tomcat,Apache Tomcat 是一個流行的開放源代碼應用服務器。J2EE 還定義了必須如何打包 Web 應用程序,因此您可以將自己開發的應用程序引入某個 J2EE 環境,無需更改代碼或重新編譯應用程序,就能將它重新部署到另一個應用服務器中。將應用程序部署到多個平台也是如此。

應用服務器如何運行 servlet 和 JSP 代碼

正如前面提到過的,J2EE 規范強制一種部署 Java Servlet 和其他 J2EE 組件的標准格式。一個稱為 部署描述符的 XML 文檔就是這種標准格式的一部分。部署描述符包含從每個 servlet 到用於調用特定 servlet 的 URL 的映射。應用服務器使用部署描述符中的信息來決定應該針對給定的請求調用哪個 servlet。

應用服務器調用 JSP 頁面的方式類似於 ASP.NET 運行庫調用 ASP.NET 頁面的方式。 J2EE 應用服務器將每個 JSP 頁面轉換為一個單獨的特殊 servlet,它在該頁面被請求時編譯和運行。這個特殊的 servlet 保持加載在內存中,直至 JSP 文件改變。這樣最大限度地降低了必須為每個 JSP 頁面創建和編譯一個類所導致的性能影響。

模型-視圖-控制器(MVC)體系結構

J2EE 是在考慮到一個特定的應用程序結構的情況下開發的,這個結構稱為 模型-視圖-控制器(Model-View-Controller,MVC)。MVC 定義了三個應用程序層之間的清楚分離:

模型:應用程序的數據和業務規則集——通常稱為應用程序的業務邏輯。

視圖:應用程序的用戶界面。

控制器:定義了應用程序如何對用戶輸入或模型層的變化作出反應——通常稱為應用邏輯。

MVC 體系結構的優點

J2EE 中沒有任何東西強迫您使用 MVC 體系結構來組織應用程序,但是存在這樣做的許多很好理由。通過定義三個層之間的清楚分離,MVC 允許構成每個層的組件之間的松散耦合。這樣使得組件更加可復用和更靈活。例如,假設您的需求之一是支持某個 Web 應用程序中相同數據的不同類型的視圖,因為不同的部門需要數據庫中相同數據的不同子集。您需要開發特定於每個必需子集的新的視圖組件。如果視圖邏輯和數據庫訪問代碼是緊密耦合的——ASP.NET 頁面就是將數據庫訪問代碼和 HTML 交織在一起,那麼每個視圖都要包含數據庫訪問代碼。維護重復的代碼不僅需要大量的工作,而且還可能導致出錯。MVC 體系結構在這種場景中使用數據庫代碼作為該模型的一部分,而不同的視圖組件可以復用它。

J2EE 組件和 MVC

圖 1 顯示了我們到目前為止所討論的 J2EE 組件如何映射到一個 MVC 體系結構。注意模型和視圖之間不存在任何聯系。控制器的功能是充當兩者之間的中轉站。

圖 1. MVC 與 J2EE Web 應用程序

在典型場景中,用戶提交一個其目標是一個 servlet 的 HTML。servlet 分析輸入,並使用模型中的類來調用業務邏輯以滿足該請求。然後 servlet 將結果傳遞給一個 JSP 頁面,以便向用戶顯示那些結果。

JavaServer Faces

您或許使用過 Web Forms 來開發 ASP.NET 應用程序的用戶界面和 UI 控制邏輯。 JavaServer Faces(JSF)規范提供了 J2EE 編程世界中的等價功能。像 Web Forms 一樣,JSF 提供運行庫組件,這些組件允許工具廠商為基於 Web 的 UI 開發提供拖放功能。它還允許廠商開發可供他們的開發工具使用的自定義組件。

要看到 JSF 的實際應用,可考察一下 WebSphere Studio 5.11 版中的系列工具(請參閱 參考資料)。WebSphere Studio 還有一個名為 Page Designer 的完全集成的工具,可以使用它通過拖放操作來可視化地開發 HTML 頁面和 JSP 頁面。Page Designer 已實現了 JavaServer Faces 規范,您在使用它時應該會看到一些熟悉的組件,比如 HTML 表單、DataGrids 和 DataList。您還會看到熟悉的“代碼分離(code behind)文件(使用 Java 語言),它們包含特定頁面的 UI 事件處理代碼。

JSF 環境的一個傑出特性在於,它允許您將頁面分組為符合邏輯的樹形結構。例如,如果有一組包含多個表單的頁面,那麼 JSF 樹形結構就很理想——特別是在用戶可能基於先前的輸入或基於某些用戶特征,通過一條不同的路徑經歷那些頁面的情況下。該結構為樹中的每個頁面指定一個合理的名稱。您在自己的事件處理代碼中使用這些名稱來導航不同的分支,具體取決於特定的運行時條件。

其他 J2EE 技術

Java Servlets 和 JSP 技術為您提供用 Java 語言開發平台無關的 Web 應用程序所需要的工具。其他一些 J2EE 規范和組件為您帶來更高級的功能:

Enterprise JavaBeans(EJB)技術:企業組件(或者說 bean)存在三種形式:

會話 bean:類似於 .NET 中的 COM+ 服務的特殊 Java 類。像 COM+ 服務一樣,會話 bean 在容器中運行,容器提供諸如聲明事務管理、基於角色的安全、分布式環境中的無縫訪問以及根據需要激活等服務。會話 bean 又存在兩種形式:

無狀態的:方法調用之間沒有維護狀態,因此您必須提供通過參數來調用某個方法時所需要的全部信息。無狀態會話 bean 的優點在於,容器可以使用任何實例來服務於任何客戶機調用。

有狀態的:方法調用之間的狀態得到保持,以便客戶機總是與特定的實例相關聯。有狀態的會話 bean 的優點在於,客戶機可以使用對話模式來與有狀態的會話 bean 交互。當重新創建中間狀態信息的成本很昂貴時,這是特別有用的。

實體 bean:可看作是 ADO.NET DataSets 的更高級實現的特殊 Java 類。雖然概念上類似於 DataSets,但是實體 bean 的實現更像是 COM+ 服務。像 DataSets 一樣,它們是存儲在關系數據庫或其他持久存儲中的持久數據的對象表示,並且可以封裝數據模型中的表之間的關系。像 COM+ 服務一樣,它們在容器中運行,容器提供諸如聲明事務管理、基於角色的安全、分布式環境中的無縫訪問等服務。實體 bean 是共享對象,因此容器還要處理並發控制,並確保底層的持久數據保持其 ACID(Atomicity、Consistency、Isolation 和 Durability——原子性、一致性、隔離性和持久性)屬性。(與會話 bean 不同,實體 bean 是共享對象,因此多個客戶機可以並發地訪問單個實例。)簡而言之,實體 bean 防止您直接訪問底層的持久存儲。無需作出任何應用程序更改,就可以將它們部署到各種不同的持久存儲中。(也就是說,無需改動任何代碼,就可以在部署時將實體 bean 映射到它的持久存儲。)

消息驅動的 bean:充當 JMS 相容的消息中間件的監聽器的特殊 Java 類。JMS 是用於訪問消息隊列的標准 Java API。可以將消息驅動的 bean 配置為指向特定的消息隊列;容器會在消息到達該隊列中時激活它們。消息驅動的 bean 給應用程序提供了在消息到達時調用的應用邏輯。每種 J2EE 1.3 相容的應用服務器都必須提供一個 JMS 實現,不過您也可以使用諸如 WebSphere MQ(以前名為 MQSeries)這樣的流行消息中間件。

Java 連接器體系結構(Java Connector Architecture,JCA):用於訪問許多諸如 CICS、IMS、ERP 和 CRM 這樣的遺留 EIS 系統的標准 API。JCA 把您解放出來,從此不必再學習針對每種 EIS 系統的單獨 API。

Java 編程基礎

在深入某些 J2EE 編程概念之前,我們首先向您介紹 Java 編程語言。可以使用 Java 語言來編寫服務器端應用程序以及具有 GUI 的桌面應用程序。本文假設您想要在服務器端使用 Java 語言來補充一個基於 Web 的界面,因此我們將跳過 CUI 編程環境,而是重點關注該平台的非可視化方面。我們首先介紹 Java 軟件開發包(Java Software Development Kit,SDK),然後向您展示如何使用 Java 代碼來編寫歷史悠久的 Hello World 應用程序。之後,我們將更深入地介紹兩種最流行的 .NET 語言(Visual Basic .NET 和 C#)與 Java 語言之間的區別。感謝 Scott Stricker 對本節和下面兩節所做的貢獻,這些內容節選自他的教程“Java programming for C/C++ developers”(請參閱 參考資料)。

Java SDK 簡介

Java SDK 是編寫和運行 Java 程序所需要的一組命令行工具和包。Java 程序通過即時(Just In Time,JIT)編譯器編譯為平台無關的字節代碼,然後該字節代碼可以在運行時編譯為本機代碼。其中最重要的工具是 Java 編譯器(javac.exe)和 Java 解釋器(java.exe),後者用於運行 Java 程序。該 SDK 還包括基礎的類(稱為 Java 平台),它們提供您開始編寫應用程序所需要的基本功能和 API。

Sun Microsystems 已發布了針對其每個主要 Java 平台版本的 SDK。我們推薦您獲取最新的 SDK 版本(Java 1.4.2)來完成本教程的學習。Java SDK 是免費可用的。如果您還沒有擁有它,請馬上下載它(請參閱 參考資料)。

你可以在線參考 Java 2 Standard Edition(J2SE)API 文檔(請參閱 參考資料)。它是一個 HTML 文檔集合,您可以在標准的 Web 浏覽器中浏覽它們。該 API 文檔是必備的參考資料,您或許會頻繁地使用它。

安裝 SDK

在下載 SDK 之後,您需要將它安裝到機器上。安裝過程很簡單。如果安裝程序讓您在典型安裝和自定義安裝之間的選擇,請選擇典型安裝。(僅當您准確知道自己在做什麼,並且不希望給機器增加負載時,才應該選擇自定義安裝。)安裝過程通常提供安裝標准 Java 平台類的源代碼的選項。如果機器上有充足的磁盤空間,我們推薦您接受這個選項。這些文件將為您提供一個機會,讓您考察組成 Java 語言和標准 API 的類的實現。它們設計和實現得特別好,您可以從中學到很多知識。

在安裝 SDK 之後,您可能需要配置它,以使它能在您的系統上工作。如何配置 SDK 取決於您的操作系統和所使用的 SDK 版本。該 SDK 包括完整的安裝和配置說明。

第一個 Java 程序

現在您可以編寫自己的第一個 Java 程序——無處不在的 Hello World 程序。打開文本編輯器,輸入您從清單 1 中准確看到的源代碼。

清單 1. Hello World 程序

public class HelloWorld {
  public static void main(String[] args) {
   System.out.println("Hello World");
  }
}

Java 語言是大小寫敏感的,諸如 class 和 public 這樣的關鍵字總是小寫的。可以使用任意大小寫字母組合來表示變量和方法名稱,只要您在整個給定的類中一致地使用它們。當您完成鍵入時,請把代碼保存為一個名為 HelloWorld.java 的文件。對於這個文件名,您沒有其他的選擇。Java 源文件使用 .java 擴展名,並且每個 Java 源代碼文件都 必須與您在其中定義的類具有完全相同的名稱。我們已經多次重申了:大小寫是很重要的,因此像 HELLOWORLD.JAVA 和 Helloworld.java 這樣的文件名將導致編譯錯誤。 您可以將 HelloWorld.java 保存在機器上任何適當的目錄中。您需要轉到這個目錄來使用命令行工具,因此要確保該目錄便於訪問。

編譯程序

現在就准備好可以編譯 HelloWorld 程序了。SDK 附帶的 Java 語言編譯器是一個名為 javac.exe 的命令行應用程序。要編譯一個 Java 源代碼文件,您只需將 .java 文件的名稱傳遞給 javac.exe 程序。要編譯這個 HelloWorld 程序,請打開一個命令提示符窗口,將目錄切換到您保存 HelloWorld.java 文件的位置。然後執行下面這個命令:

javac HelloWorld.java

像 Visual Basic .NET 或 C# 編譯器一樣,Java 編譯器可能生成任意數目的錯誤。自然地,您需要糾正所有錯誤,Java 編譯器才會成功地編譯 HelloWorld 程序。成功的編譯將生成一個名為 HelloWorld.class 的類文件。這個文件代表您將在 Java 解釋器中運行的可執行文件。

運行程序

SDK 附帶的 Java 語言解釋器是一個名為 java.exe 的命令行應用程序。要運行一個 Java 字節代碼可執行文件,您只需將該 java 程序的名稱傳遞給 java 解釋器。在使用 Java 解釋器時不要指定 .class 擴展名。解釋器僅接受類文件,因此添加 .class 擴展名將產生一個錯誤。要運行這個 HelloWorld 程序,請打開一個命令提示符窗口,將目錄切換到您編譯 HelloWorld.java 文件的位置。這個字節代碼可執行文件 HelloWorld.class 應該就在該目錄中。然後執行下面這個命令:

java HelloWorld

Java 解釋器嘗試執行 HelloWorld 程序的 main() 方法。Java 程序的 main() 方法等價於控制台應用程序使用的 Visual Basic .NET Sub Main() 或 C# Main() 方法。返回類型為 void 的 Java 方法等價於 Visual Basic .NET 中的 Sub 。具有其他返回類型的方法等價於 Visual Basic .NET 中的 Function 。

Java 解釋器可能會報告運行時錯誤,這通常會終止程序執行。與在 Visual Basic .NET 和 C# 中一樣,Java 運行時錯誤要比編譯時錯誤更難於調試,不過沒有編譯時錯誤出現得那麼頻繁。像 .NET 程序一樣,Java 程序在一個托管環境中執行,因此您可以寬限地處理運行時錯誤。

Java 語言與 Visual Basic .NET 之比較

現在讓我們考察一下 Java 語言與 Visual Basic .NET 之間的區別。(如果您純粹是個 C# 開發人員,可以跳到本文後面的 Java 語言與 C# 之比較小節。)

類型

Java 語言和 Visual Basic .NET 都是單繼承的面向對象語言,它們具有一個作為其他所有類的基類的類:Visual Basic .NET 中的 System.Object 和 Java 語言中的 java.lang.Object 。這意味著對於您開發的類層次,兩種語言是相似的。如果沿著層次樹往上,您最終會到達對應的根類。

Java 語言使用了原始類型(primitive type)的概念,它們非常類似 C 和 C++ 中的對應概念。它們不是任何類層次的一部分,也不具有任何方法。此外,當使用它們作為參數時,它們總是按值傳遞。表 1 列出了 Java 語言中的原始類型和它們在 Visual Basic .NET 中的等價類型:

表 1 Java 語言中的原始類型和它們在 Visual Basic .NET 中的等價類型

Java 原始類型 描述 等價的 Visual Basic .NET 類型 描述 int 32 位有符號整數 Integer 32 位有符號整數 long 64 位有符號整數 long 32 位有符號整數 short 16 位有符號整數 short 16 位有符號整數 char 16 位無符號整數 Char 16 位無符號整數 byte 8 位無符號整數 Byte 8 位無符號整數 boolean 有效值是 true或者 false Boolean 有效值為 true或者 false float 32 位浮點數 Single 32 位浮點數 double 64 位浮點數 Double 64 位浮點數

在 Java 語言中,每種原始類型具有一個對應的包裝類,可以使用它將該類型作為對象而不是作為原始類型來處理。每個包裝類具有一個構造函數,允許您根據原始類型中的數據創建該包裝類型的一個實例。在 Visual Basic .NET 中,您可以隱式地將對應的類型轉換為 Object 的一個實例,因此不需要在這種情形下使用包裝類。清單 2 中的例子突出了它們之間的區別。

清單 2. 原始類型和它們的包裝類

Visual Basic .NET           Java
Module Foo                 public class Foo
                      {
  Sub someMethod(ByRef arg As Object)    private void someMethod(Object arg) {
   ' do something with arg           // do something with arg
  end Sub                   }
  Sub Main()                 public static void main(String[] args) {
   Dim i = 0 As Integer                int i=0;
                         Foo x = new Foo();
   someMethod(i);               x.someMethod(new Integer(i));
  End Sub                   }
End Module                 }

清單 2 中的 Java 原始類型被顯式地包裝在 Object 的一個派生類中,而在 Visual Basic .NET 中,這種轉換是隱式的。

注意在 Java 語言中,原始類型是按值傳遞的。對象實例內部地使用指針來表示,這些指針也是按值傳遞的(也就是指針的值,而不是指針所指向的內容)。在 Visual Basic .NET 中,默認的行為是值類型按值傳遞,引用類型按引用傳遞。Java 語言中沒有等價於 Visual Basic .NET ByRef 和 ByVal 的關鍵字。表 2 顯示了等價於 Visual Basic .NET 類型但是沒有映射到 Java 原始類型的 Java 語言類型。

表 2 常用的 Java 系統類和它們在 Visual Basic .NET 中的等價類型

Java 類 描述 等價的 Visual Basic .NET 類 描述 java.lang.Object 任何非原始類型都是 Object 的派生類 Object 每種類型都是 Object 的派生類 java.lang.String Unicode 字符 String Unicode 字符 java.math.BigDecimal 可調整進位制的 32 位小數 Decimal 可調整進位制的 32 位小數 java.util.Date 日期(排除時間部分) Date 日期(排除時間部分)

Java 語言與 Visual Basic .NET 不同,它沒有結構和模塊。所有 Java 代碼都必須是某個類或接口的一部分。如果要移植包含模塊和結構的 Visual Basic .NET 代碼,您必須將它們改寫為 Java 類。

繼承和接口

兩種語言都僅允許單繼承,但是都允許實現多個接口。這在兩種語言中的實現方式有所不同。例如,清單 3 顯示了如何從一個名為 Parent 的類派生子類並實現兩個分別名為 IOne 和 ITwo 的接口。

清單 3 派生子類並實現接口

Visual Basic .NET      Java
Public Class Child        public class Child extends Parent implements IOne, ITwo
  Inherits Parent        {
  Implements IOne         ...
  Implements ITwo        }
  ...
End Class

在 Java 語言中, extends 關鍵字表示繼承, implements 關鍵字表示實現一個或多個接口,接口之間用逗號分隔。

如果熟悉 Visual Basic .NET 中的名稱空間,那麼對 Java 語言中的包就不應該有任何概念問題。像名稱空間一樣,包允許您組織類以避免當您在不同上下文中使用相同名稱的類時存在的名稱沖突。名稱空間的邏輯類分組促進了類復用,使得導航大量的類成員更加容易。在 Java 語言中,您需要通過兩種方式處理這種分組:如何將類聲明為特定包的成員,以及如何引用特定包中的類。清單 4 中的例子說明了名稱空間和包的處理。

清單 4. 名稱空間和包

Visual Basic .NET           Java
 'Foo will be in this namespace      // Foo will be in this package
Namespace MyApp.Utilities         package com.mycompany.myapp.utilities;
Public class Foo             public class Foo
                      {
  ...                    ...
End Class                 }
End Namespace
 'using Foo in another class       // using Foo in another class
Imports MyApp.Utilities.Foo       import com.mycompany.myapp.utilities.Foo;
Public Class Foo2            public class Foo2
  ...                  {
                       ...
End Class                }

在 Java 語言中,約定的做法是包名稱全部使用小寫,並使用反向的 Internet 域名作為每個包的前綴。上述清單使用 Java import 語句(類似 Visual Basic .NET Imports 語句)來引用 Foo2 中的 Foo 類,而沒有使用完全限定的名稱(Visual Basic .NET 中的 MyApp.Utilities.Foo 或 Java 代碼中的 com.mycompany.myapp.utilities.Foo )。

打包以供復用

在 Visual Basic .NET 中,您可以編寫一組類,把它們生成程序集(assembly),程序集在文件系統中表示為動態鏈接庫。其他類可以引用這些程序集,以便使用它們所包含的類。Java 語言也允許把一組類打包到一個稱為“Java 歸檔(Java Archive,JAR)文件”的文件中以供復用。您可以將一組類組合到一個帶有 .jar 擴展名的文件中,然後在其他類中引用該 JAR 文件。具有 .jar 擴展名的文件是標准的 zip 文件,可以使用 WinZip 或其他壓縮實用程序來操作它們。不過為方便起見,Java SDK 包含了一個名為 jar.exe 的實用程序(在 Windows 平台上),可以使用它來把一組類組合到一個具有 .jar 擴展名的文件中。

在考察使用 jar.exe 實用程序的例子之前,理解包名稱和 Java 平台用於生成類以及在運行時加載它們的目錄結構之間的關系是很重要的。請考慮一個名為 Test的類,它的源代碼在一個名為 Test.java 的文件中。如果將 Test.java 定義為包 com.mycompany.test的一部分,那麼編譯器會為結果類模塊創建一個目錄樹。該目錄樹就建立在包名稱的基礎上。此例中該目錄樹為 com\mycompany\test,並且包名稱中的點號被轉換為目錄邊界(分隔符 \)。

現在打開一個命令提示符窗口,然後創建一個目錄(例如 c:\javapack)。切換到該目錄( cd javapack)。使用您最喜歡的文本編輯器,將清單 5 中的代碼添加到一個名為 Test.java 的新文件中。

清單 5. 使用包的例子

package com.mycompany.test;
public class Test
{
  public static void main(String[] args) {
    System.out.println("In test");
  }
}

現在使用以下命令編譯 Test.java。( -d 選項應該指向您為這個例子創建的目錄):

java -d c:\javapack Test.java

現在在 c:\javapack 目錄下應該有一個名為 com 的子目錄。事實上,您可以看到編譯所產生的 comTest.class 文件的完全限定名稱是 Test.class。注意包名稱( com.mycompany.test)是如何轉換為對應目錄結構(com\mycompany\test)的,該目錄結構以您使用 -d選項指定的目錄作為根目錄。

下面我們將展示如何打包 Test.class 以方便其他類復用。從 c:\javapack 目錄運行以下命令:

jar -cvf Test.jar com

這個命令將創建一個名為 Test.jar 的文件,它包含 com 子目錄下的所有類。

運行以下命令來使用 Test.jar 文件中的類:

java -classpath Test.jar com.mycompany.test.Test

注意您必須使用完全限定的類名稱來從命令行運行該命令,而且還要注意使用 -classpath 選項來指向 Test.jar 文件的方式。或者,您可以把 Test.jar 文件添加到 CLASSPATH 環境變量中,該變量是分號分隔的 JAR 文件列表,以及 Java 編譯器和 Java 虛擬機(Java virtual machine,JVM)用來尋找需要加載的類的目錄列表。

訪問修飾符

訪問修飾符 public 、 private 和 protected 在兩種語言中的工作方式大部分都是相同的。 在 Visual Basic .NET 中,默認的訪問修飾符是 Friend 。在 Java 語言中,默認的訪問權限是允許任何子類或相同包中的任何類訪問當前類、字段或方法。這大致等價於 Visual Basic .NET 中的 Protected Friend 修飾符,該修飾符僅允許從相同程序集或從子類訪問。

方法重載

Visual Basic .NET 中的子類如果要重載父內中的某個方法:

該方法一定 不 能在父類中使用 private 訪問修飾符來聲明。

該方法必須在父類中聲明為 Overridable 。

子類中的方法必須與父類中的對應方法具有相同的名稱、返回類型和參數簽名。

子類中的方法必須使用 Overrides 關鍵字來聲明。(您也可以使用 new 關鍵字,但是一般不推薦這樣做。)

父類中的方法一定 不 能聲明為 NotOverridable 。

Java 語言中方法重載的前提條件不太嚴格:

該方法一定 不 能在父類中使用 private 訪問修飾符來聲明。

子類中的方法必須與父類中的對應方法具有相同的名稱、返回類型和參數簽名。

父類中的方法一定 不 能聲明為 final 。

這些區別的含義是,在 Java 代碼中,子類中不可能包含與父類中的非私有方法具有相同名稱和簽名的方法而不會隱含地重載它。在 Visual Basic .NET 中,您必須顯式地指明何時想要重載父類中的方法。還要注意,Java 語言中的 final 關鍵字或多或少地等價於 Visual Basic .NET 中的 NotOverridable 關鍵字。

異常處理

結構化的異常處理在兩種語言中幾乎完全相同。(兩者都可以往後追溯到一份創始性的論文,即 Andrew Koenig 和 Bjarne Stroustrup 於 1990 年撰寫的 Exception Handling for C++。) 兩種語言都使用兩種異常概念:應用程序生成的異常,以及系統運行庫(Visual Basic .NET 的公共語言運行庫,Java 語言的 JVM)生成的異常。 兩種語言都具有 Exception 基類,應用程序異常和系統異常都是由它派生而來的。圖 2 顯示了每種語言中的 Exception 類層次。

圖2. Java 語言和 Visual Basic .NET 中的 Exception 類

然而,兩種語言的編譯器對您的代碼如何處理異常具有不同的預期。在 Visual Basic .NET 中,您可以選擇捕獲異常,或讓它們沿調用堆棧向上傳播到類的方法的調用者(和/或構造函數)。Java 語言允許同樣的處理,但是對於未捕獲的應用程序異常(也就是 java.lang.Exception 的子類),您必須顯式地將它們作為方法聲明的一部分來列出。因此 Java 編譯器預期您或者自己捕獲所有應用程序異常,或者告訴編譯器關於未捕獲的異常的信息。例如,假設 Foo 類的構造函數可能拋出一個應用程序異常,那麼清單 6 中的 Visual Basic .NET 或 Java 代碼對各自的編譯器來說都不會有問題。

清單 6. 處理應用程序異常

Visual Basic .NET           Java
...                     ...
Sub SomeMethod()              public void someMethod() {
  Try                    try {
  Dim Foo X As New Foo()              Foo x = new Foo();
                       }
  Catch e As ApplicationException      catch (Exception e)
                       {
  ...                     ...
  End Try                  }
End Sub                   }

然而,如果改變代碼以使其不捕獲異常,那麼您就必須改變 Java 方法聲明(如清單 7 所示)以避免編譯器錯誤。

清單 7. 未捕獲的應用程序異常

Visual Basic .NET           Java
...                    ...
Sub SomeMethod()              public void someMethod() throws Exception {
 Dim Foo X As New Foo();           Foo x = new Foo();
End Sub                  }

兩種語言在這方面存在的另一個區別在於,在 Visual Basic .NET 中,每個捕獲塊的參數是可選的。如果省略它,那麼所有異常都會被捕獲。Java 語言不允許這樣,而是允許一個等價功能( java.lang.Throwable ),它捕獲所有異常類的父類,如清單 8 所示。

清單 8. 捕獲所有異常

Visual Basic .NET           Java
...                     ...
Sub SomeMethod()              public void someMethod() {
  Try                    try {
  Dim Foo X As New Foo()              Foo x = new Foo();
                       }
  Catch                   catch (Throwable e)
                       {
  ...                     ...
  End Try                  }

數組聲明

Java 語言提供兩種聲明數組的方法;Visual Basic .NET 僅提供了一種方法。Java 數組工作起來很像 Visual Basic .NET 中的動態數組:必須通過一個顯式的步驟來給它分配內存。清單 9 中的代碼說明了這個區別。與在 Visual Basic .NET 中一樣,Java 數組的下標從 0 開始。

清單 9. 聲明數組

Visual Basic .NET         Java
...                  ...
' This is how an array is       // In Java the following
'declared in Visual Basic .NET     // are both allowed
Dim MyArray() As Integer        private int[] myArray;
                    // or
                    private int myArray[];
'Allocate some storage for the array  // Allocate some storage
                    // for the array
ReDim MyArray(30)           myArray = new int[30];

委托

Java 語言沒有直接等價於 Visual Basic .NET 委托的結構。可以通過聲明並實現一個具有單個方法定義的接口來模擬委托功能。

變量聲明

Java 語言是強類型的,控制變量聲明的規則等價於打開 Option Explicit 選項後的 Visual Basic .NET 規則。也就是說,您必須在使用變量之前聲明它們。Java 語言不允許改變這個性質。

OnError GoTo

Java 語言沒有直接等價於 Visual Basic .NET 的 GoTo 語句的結構。不過,您可以使用異常處理機制相當容易地執行異常處理。

構造函數

像 Visual Basic .NET 一樣,Java 類可以包含具有不同參數列表的不同構造函數。在 Visual Basic .NET 中,構造函數通過名為 New() 的 Sub 來聲明。Java 語言構造函數的名稱與類名稱相同。清單 10 中的代碼說明了這個區別。

清單 10:構造函數

等價的 Visual Basic .NET 類型
Public Class Foo                 public class Foo {
  Private MyVar As Integer             private int myVar;
  Public Sub New(ByVal NewVal As Integer)      public Foo(int newVal) {
   MyVar = NewVal                  myVar = newVal;
  End Sub                      }
  ...                        ...
End Class                     }

屬性(property)

等價於 Visual Basic .NET 屬性的 Java 結構稱為 字段(field)。在 Java 語言中,您不能將 getter 和 setter 定義為字段定義的一部分,但是可以向類中聲明那些字段的地方添加 getter 和 setter。清單 11 中的代碼說明了這個區別。

清單 11:屬性

Visual Basic .NET           Java
Public Class Foo              public class Foo {
  Private MyPropVal As String         private String myProp;
  Public Property MyProp() As String      public String getMyProp() {
   Get                     return myProp;
     Return MyPropVal            }
   End Get
   Set(ByVal NewValue As String)       public void setMyProp(String newValue) {
     MyPropVal = NewValue           myProp = newValue;
   End Set                  }
  End Property
  ...                      ...
End Class                  }

小結

Visual Basic .NET 的語法類似於以前的 Visual Basic 版本,但是最新的版本包括了許多可從 Java 語言中找到的面向對象特性。繼承、接口和異常處理就是兩種語言的實現存在相似性的一些方面。與以前版本的 Visual Basic 相比,這種相似性應該使您轉向 Java 平台更加容易。我們提倡您首先把 Visual Basic .NET 小程序轉換到 Java 語言。不要忘了使用 Java 平台文檔,要查找功能上等價於 System... 名稱空間中的 Visual Basic .NET 類的 Java 類,您會發現這些文檔非常有用。

Java 語言與 C# 之比較

下面讓我們考察 Java 語言和 C# 之間的區別。這兩種語言具有許多相似之處,因此我們將重點關注其區別所在。

類型

Java 語言和 C# 都是單繼承的面向對象語言,它們都具有一個作為其他所有類的基類的類:C# 中的 System.object 和 Java 語言中的 java.lang.Object 。這意味著對於您開發的類層次,兩種語言是相似的。如果沿著層次樹往上,您最終會到達對應的根類。

Java 語言使用了原始類型(primitive type)的概念,它們非常類似 C 和 C++ 中的對應概念。它們不是任何類層次的一部分,也不具有任何方法。此外,當使用它們作為參數時,它們總是按值傳遞。表 3 列出了 Java 語言中的原始類型和它們在 C# 中的等價類型:

表 3 Java 語言中的原始類型和它們在 C# 中的等價類型

Java 原始類型 描述 等價的 C# 類型 描述 int 32 位有符號整數 int 32 位有符號整數 long 64 位有符號整數 long 32 位有符號整數 short 16 位有符號整數 short 16 位有符號整數 char 16 位無符號整數 char 16 位無符號整數 byte 8 位無符號整數 byte 8 位無符號整數 boolean 有效值是 true或者 false bool 有效值是 true或者 false float 32 位浮點數 float 32 位浮點數 double 64 位浮點數 double 64 位浮點數

在 Java 語言中,每種原始類型具有一個對應的包裝類,可以使用它將該類型作為對象而不是作為原始類型來處理。每個包裝類具有一個構造函數,允許您根據原始類型中的數據創建該包裝類型的一個實例。 在 C# 中,您可以隱式地將對應的類型轉換為 object 的一個實例,因此不需要在這種情形下使用包裝類。清單 12 中的代碼突出了它們之間的區別。

清單 12. 原始類型和它們的包裝類的例子

C#                     Java
public class Foo                 public class Foo
{                        {
 private void someMethod(object arg) {      private void someMethod(Object arg) {
   // do something with arg             // do something with arg
 }                        }
 public static void Main(string[] args) {     public static void main(String[] args) {
   int i = 0;                        int i=0;
   Foo x = new Foo();                Foo x = new Foo();
   x.someMethod(i);                 x.someMethod(new Integer(i));
 }                        }
}                         }

清單 12 中的 Java 原始類型被顯式地包裝在 Object 的一個派生類中,而在 C# 中,這種轉換是隱式的。(C# 中隱式的轉換稱為 裝箱(boxing)。)

注意在 Java 語言中,原始類型是按值傳遞的,對象類型在內部使用指針來表示,它們也是按值傳遞的。C# 中的默認行為是相同的,不過該語言還包括 ref 關鍵字來強制將值類型作為引用來傳遞。

表 4 顯示了一些等價於 C# 類型但是沒有映射到 Java 原始類型的 Java 語言類型。

表 4 C# 類型和它們的 Java 等價類型

等價的 Java 類型 描述 C# 類型 描述 java.lang.Object 任何非原始類型都是 Object 的派生類 object 每種類型都是 object 的派生類 java.lang.String Unicode 字符 string Unicode 字符 java.math.BigDecimal 可調整進位制的 32 位小數 decimal 可調整進位制的 32 位小數

繼承和接口

兩種語言都僅允許單繼承,但是都允許實現多個接口。這在兩種語言中的實現方式有所不同。例如,清單 13 顯示了如何從一個名為 Parent 的類派生子類,並實現兩個分別名為 IOne 和 ITwo 的接口。

清單 13 派生子類並實現接口

C#                  Java
public class Child : Parent, IOne, ITwo  public class Child extends Parent implements IOne, ITwo
{                     {
  ...                    ...
}                     }

注意在 Java 語言中, extends 關鍵字表示繼承, implements 關鍵字表示一個或多個接口的實現。

如果熟悉 C# 中的名稱空間,那麼對 Java 語言中的包就不應該有任何概念問題。像名稱空間一樣,包允許您組織類以避免當您在不同上下文中使用相同名稱的類時存在的名稱沖突。名稱空間的邏輯類分組促進了類復用,使得導航大量的類成員更加容易。在 Java 語言中,您需要通過兩種方式處理這種分組:如何將類聲明為特定包的成員,以及如何引用特定包中的類。清單 14 中的例子說明了名稱空間和包的處理。

清單 14. 名稱空間和包

C#                 Java
// Foo will be in this namespace     // Foo will be in this package
namespace MyApp.Utilities        package com.mycompany.myapp.utilities;
public class Foo             public class Foo
{                    {
 ...                   ...
}                    }
// using Foo in another class      // using Foo in another class
using MyApp.Utilities.Foo;        import com.mycompany.myapp.utilities.Foo;
public class Foo2            public class Foo2
{                    {
  ...                   ...
}                    }

注意在 Java 語言中,約定的做法是包名稱全部使用小寫,並使用反向的 Internet 域名作為每個包的前綴。上述清單使用 Java import 語句(類似 C# using 語句)來引用 Foo2 中的 Foo 類,而沒有使用完全限定的名稱(C# 中的 MyApp.Utilities.Foo 或 Java 語言中的 com.mycompany.myapp.utilities.Foo )。

打包以供復用

在 C# 中,您可以編寫一組類,把它們生成程序集(assembly),程序集在文件系統中表示為動態鏈接庫。其他類可以引用這些程序集,以便使用它們所包含的類。Java 語言也允許把一組類打包到一個稱為 Java 歸檔(Java Archive,JAR)文件的文件中以供復用。您可以將一組類組合到一個帶有 .jar 擴展名的文件中,然後在其他類中引用該 JAR 文件。具有 .jar 擴展名的文件是標准的 zip 文件,可以使用 WinZip 或其他壓縮實用程序來操作它們。不過為方便起見,Java SDK 包含了一個名為 jar.exe 的實用程序(在 Windows 平台上),可以使用它來把一組類組合到一個具有 .jar 擴展名的文件中。

在考察使用 jar.exe 實用程序的例子之前,理解包名稱和 Java 平台用於生成類以及在運行時加載它們的目錄結構之間的關系是很重要的。請考慮一個名為 Test的類,它的源代碼在一個名為 Test.java 的文件中。如果將 Test.java 定義為包 com.mycompany.test的一部分,那麼編譯器會為結果類模塊創建一個目錄樹。該目錄樹就建立在包名稱的基礎上。此例中該目錄樹為 com\mycompany\test,並且包名稱中的點號被轉換為目錄邊界(分隔符 \)。

現在打開一個命令提示符窗口,然後創建一個目錄(例如 c:\javapack)。切換到該目錄( cd javapack)。使用您最喜歡的文本編輯器,將清單 15 中的代碼添加到一個名為 Test.java 的新文件中。

清單 15. 使用包的例子

package com.mycompany.test;
public class Test
{
  public static void main(String[] args) {
    System.out.println("In test");
  }
}

使用以下命令編譯 Test.java。(注意 -d 選項應該指向您為這個例子創建的目錄):

java -d c:\javapack Test.java

現在 c:\javapack 目錄下應該有一個名為 com 的子目錄。事實上,您可以看到編譯所產生的 comTest.class 文件的完全限定名稱是 Test.class。 注意包名稱( com.mycompany.test)是如何轉換為對應目錄結構(com\mycompany\test)的,該目錄結構以您使用 -d選項指定的目錄作為根目錄。

下面我們將展示如何打包 Test.class 以方便其他類復用。從 c:\javapack 目錄運行以下命令:

jar -cvf Test.jar com

jar 命令將創建一個名為 Test.jar 的文件,它包含 com 子目錄下的所有類。

執行以下命令來使用 Test.jar 文件中的類:

java -classpath Test.jar com.mycompany.test.Test

注意您必須使用完全限定的類名稱來從命令行運行該命令,而且還要注意使用 -classpath 選項來指向 Test.jar 文件的方式。或者,您可以把 Test.jar 文件添加到 CLASSPATH 環境變量中,該變量是分號分隔的 JAR 文件列表,以及 Java 編譯器和 Java 虛擬機(Java virtual machine,JVM)用來尋找需要加載的類的目錄列表。

訪問修飾符

訪問修飾符 public 、 private 和 protected 在兩種語言中的工作方式大部分都是相同的。在 C# 中,默認的訪問權限是 private ;Java 語言中的默認行為是允許任何子類或相同包中的任何類訪問當前類、字段或方法。這大致等價於 C# 中的 internal 關鍵字,該修飾符僅允許從相同程序集訪問。

方法重載

C# 中的子類如果要重載父類中的某個方法:

該方法一定 不 能在父類中使用 private 訪問修飾符(或沒有訪問修飾符)來聲明。

該方法必須在父類中聲明為 virtual 。

子類中的重載方法必須與父類中的方法具有相同的名稱、返回類型和參數簽名。

子類中的方法必須使用 Overrides 關鍵字來聲明。(您也可以使用 new 關鍵字,但是一般不推薦這樣做。)

父類中的方法一定 不 能聲明為 sealed 。

Java 語言中方法重載的前提條件不太嚴格:

該方法一定 不 能在父類中使用 private 訪問修飾符來聲明。

子類中的方法必須與父類中的對應方法具有相同的名稱、返回類型和參數簽名。

父類中的方法一定 不 能聲明為 final 。

這些區別的含義是,在 Java 代碼中,子類中不可能包含與父類中的非私有方法具有相同名稱和簽名的方法而不會隱式地重載它。在 C# 中,您必須顯式地指明何時想要重載父類中的方法。還要注意 Java 語言中的 final 關鍵字如何或多或少地等價於 C# 中的 sealed 關鍵字。

異常處理

結構化的異常處理在兩種語言中幾乎完全相同。(兩者都可以往後追溯到一份創始性的論文,即 Andrew Koenig 和 Bjarne Stroustrup 於 1990 年撰寫的 Exception Handling for C++。) 兩種語言都使用了兩種異常概念:應用程序生成的異常,以及系統運行庫(C# 的公共語言運行庫,Java 語言的 JVM)生成的異常。兩種語言都具有 Exception 基類,應用程序異常和系統異常都是由它派生而來的。 圖 3 顯示了兩種語言中的 Exception 類層次。

圖3. Java 語言和 C# 中的 Exception 類層次

然而,兩種語言的編譯器對您的代碼如何處理異常具有不同的預期。在 C# 中,您可以選擇捕獲異常,或讓它們沿調用堆棧向上傳播到類的方法的調用者(和/或構造函數)。Java 語言允許同樣的處理,但是對於未捕獲的應用程序異常(也就是 java.lang.Exception 的子類),您必須顯式地將它們作為方法聲明的一部分來列出。因此 Java 編譯器預期您或者自己捕獲所有應用程序異常,或者告訴編譯器關於未捕捉的異常的信息。例如,假設 Foo 類的構造函數可能拋出一個應用程序異常,那麼清單 16 中的 C# 或 Java 代碼對各自的編譯器來說都不會有問題。

清單 16. 處理應用程序異常

C#                 Java
...                   ...
public void someMethod() {        public void someMethod() {
  try {                  try {
  Foo x = new Foo();             Foo x = new Foo();
  }                    }
  catch (ApplicationException e)      catch (Exception e)
  {                    {
  ...                    ...
  }                    }
}                    }

然而,如果改變代碼以使其不捕獲異常,那麼您就必須改變 Java 方法聲明(如清單 17 所示)以避免編譯器錯誤。

清單 17. 未捕獲的應用程序異常

C#                Java
...                 ...
public void someMethod() {      public void someMethod() throws Exception {
  Foo x = new Foo();           Foo x = new Foo();
}                  }

兩種語言在這方面存在的另一個區別在於,在 C# 中,每個捕獲塊的參數是可選的。如果省略它,那麼所有異常都會被捕獲。Java 語言不允許這樣,而是允許一個等價功能( java.lang.Throwable ),它捕獲所有異常類的父類,如清單 18 所示。

清單 18. 捕獲所有異常

C#                  Java
...                    ...
public void someMethod() {        public void someMethod() {
  try {                   try {
  Foo x = new Foo();             Foo x = new Foo();
  }                     }
  catch                   catch (Throwable e)
  {                     {
  ...                     ...
  }                     }
}                     }

數組聲明

Java 語言提供兩種聲明數組的方法;C# 僅提供了一種方法。清單 19 中的代碼說明了這個區別。

清單 19. 聲明數組

C#                    Java
...                      ...
// This is how an array is declared in C#   // In Java the following are both allowed
private int[] myArray;            private int[] myArray;
                       // or
                       private int myArray[];

委托和索引器(indexer)

Java 語言沒有直接等價於 C# 委托的結構。您可以通過聲明並實現一個具有單個方法定義的接口來模擬委托功能。

Java 語言也沒有索引器;您需要將它們編寫為常規的類方法。

操作符重載

Java 語言不允許操作符重載(這是一個從 C++ 借用來的 C# 特性)。您可以容易地編寫方法來模擬操作符重載行為。

非安全模式

C# 的非安全模式允許您使用指針和內存插接塊(pin bolck)來繞過垃圾收集。Java 運行庫本身廣泛使用了指針,但是 Java 語言沒有指針,也沒有等價的非安全模式。這樣是為了遵循 Java 平台的“編寫一次,隨處運行”的哲學,它允許你安全地避免平台依賴性、內存洩露以及“失控(runaway)”代碼。

小結

您的 C# 背景應該使得轉向 Java 平台相當容易。本文中手把手的代碼示例或許會讓您認識到:這兩種語言使用了相當類似的語法。它們在概念上也相當相似。繼承、接口和異常處理就是這兩種語言的實現幾乎完全相同的一些方面。我們提倡您首先把一些 C# 小程序轉換到 Java 語言。不要忘了使用 Java 平台文檔,要查找功能上等價於 System... 名稱空間中的 C# 類的 Java 類,您會發現這些文檔非常有用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved