天天看點

JRuby:使Java和Ruby成為一家人

一、 引言

  Ruby是現在程式設計界讨論得正熱火朝天的一種語言。這種語言功能強大而且易于使用;同時Ruby還緊密綁定 到例如Ruby on Rails等web應用程式開發架構中。另一方面,在過去的十年間,Java正迅速成長為業界領先的面向對象的軟體開發語言并且運作于諸多平台之上。而 JRuby則是一個100%的Ruby程式設計語言的純Java實作。本文是JRuby的一個入門篇;同時,還會向你展示它是如何結合Java語言的優勢,從 而提供給Java開發者一個快速而強有力的建立應用程式的可選方案的。

   二、 Ruby-席卷計算世界的腳本化語言

   近幾個月來,在程式設計領域的幾乎每一個人可能都會耳濡目染Ruby。日益盛行的Ruby on Rails web開發架構正在幫助使Ruby成為快速開發和測試應用程式的一門語言。作為一種解釋性的腳本化語言,Ruby提供了快速而容易的面向對象程式設計技術,同 時還提供了許多非常幹淨利索的特征,例如closure,塊和mixins。另外,Ruby還是高度可移植的,可以廣泛運作于Unix/Linux, Windows以及MacOS平台之上。要想全面了解Ruby,我建議你去閱讀W.Jason Gilmore的文章。

   三、 Java-輝煌的面向對象語言的十年

   Java最早由Sun Microsystems的James Gosling在上一世紀九十年代建立。當時,Gosling開發這一語言的主要目的是想提供一種虛拟機和一種C風格的标志語言,同時使之具有比C/C+ +更為一緻和更為簡單的特征。Java的另一個主要的目标是提供一種"編寫一次處處都能運作"(WORA)的理想語言,允許一個程式在一種平台上開發而能 夠不經任何重編譯即可運作于另一種平台。這個Java平台由一個Java運作時刻環境和Java軟體開發包(SDK)組成。現在,Java能夠為從移動設 備到企業系統的諸多平台提供SDK,這分别對應于它的JavaSE,EE和ME技術。在過去的十年間,Java已經被廣泛應用于移動裝置、無人值守系統、 web應用程式、金融系統以及實時系統等衆多開發領域。

   四、 JRuby-Java虛拟機(JVM)上運作的Ruby

   JRuby則是一個100%的Ruby程式設計語言的純Java實作,這種語言在CPL,GPL和LGPL三種開源許可下發行。它是一個1.8.4 Ruby解釋器,其中提供了大多數Ruby的内置類。JRuby支援從一個Ruby程式中定義Java類并實作與之互動,另外還對Bean腳本化架構實作 支援。在本文成文之時,JRuby的目前版本是0.9.1。JRuby使Ruby程式能夠存取Java類,允許它們作為程式内使用的一級對象。如今, JRuby的創始人,Thomas Enebo和Charles Nutter,已經受雇于Sun專門研究開發JRuby。

   五、 運作你的第一個JRuby程式

   JRuby的發行中帶有一個tar.gz檔案。在本文中,我基于Windows系統并使用JRuby的jruby-bin-0.9.1.tar.gz二 進制發行版本以及Java SE版本1.5.0_06。在解壓這些發行檔案後,會出現一個jruby-0.9.1檔案夾,其中包含的子檔案夾有:bin,docs,lib和 samples。注意,你可以添加一個指向這個目錄的JRUBY_HOME環境變量,然後把%JRUBY_HOME%bin(在UNIX系統上是$ JRUBY_HOMEbin)添加到你的系統路徑下。JRuby發行版的bin目錄中包含一個jruby.bat檔案,它用于運作JRuby解釋器程式。 從指令行下運作"jruby -version"可以測試JRuby是否正确工作:

C:JRubyjruby-0.9.1>jruby -version

ruby 1.8.5 (0) [java]

  在上面的samples目錄中,你可以找到一些展示JRuby功能的示例Ruby程式。作為第一個示例,你可以看一下下面這個java2.rb示例。這個示例包含了下列Ruby代碼:

require "java"

filename = "./samples/java2.rb"

fr = java.io.FileReader.new filename

br = java.io.BufferedReader.new fr

s = br.readLine

print "------ ", filename, "------n"

while s

puts s.to_s

s = br.readLine

end

print "------ ", filename, " end ------n";

br.close

  第一行代碼負責啟動JRuby的Java支援并且允許一個Ruby程式使用Java類。

   該程式定義了一個指向檔案"./samples/java2.rb"的java.io.FileReader。然後,它聲明了一個 java.io.BufferedReader用于緩沖經由FileReader讀取的資料。本文程式從這個檔案中讀取所有的代碼并且把它們輸出到控制 台。下面是使用JRuby運作這個Ruby腳本的輸出結果:

C:JRubyjruby-0.9.1>jruby .samplesjava2.rb

------ ./samples/java2.rb------

require "java"

filename = "./samples/java2.rb"

fr = java.io.FileReader.new filename

br = java.io.BufferedReader.new fr

s = br.readLine

print "------ ", filename, "------n"

while s

puts s.to_s

s = br.readLine

end

print "------ ", filename, " end ------n";

br.close

------ ./samples/java2.rb end ------

C:JRubyjruby-0.9.1>

  到現在為止,你已經能夠使用JRuby運作一個Ruby腳本;該腳本能夠使用Java類讀取一個檔案并且輸出其内容。這是JRuby向Ruby使用者展示的一個強有力的概念。

六、 在JRuby中使用Java類(包括命名沖突問題)

  現在,既然你已經能夠運作一個示例,那麼接下來,讓我們來看一下JRuby是如何允許在Ruby程式中使用Java類的。JRuby提供的最重要的方法是Kernel#include_class方法。這個方法允許Ruby按如下方式使用Java類:

require "java"

# Include Java's FileReader

include_class "java.io.FileReader"

filename = "./samples/java2.rb"

fr = FileReader.new filename

   然而,有可能在Java類和Ruby類之間存在命名沖突問題。其中,字元串的使用就是一個例子;Java中提供了java.util.String,而 Ruby中提供了Kernel::String。為了解決這個命名沖突問題,你可以在包括它時重命名這個類-通過把一個代碼塊傳遞給 include_class方法調用來實作:

require "java"

# Include Java's String as JString

include_class("java.lang.String") { |package, name| "J" + name }

s = JString.new("Hello World from JRuby!")

puts s

  通過定義一個包括Java類定義的Ruby子產品,你還能夠避免這個命名沖突:

require "java"

module JavaLang

include_package "java.lang"

end

s = JavaLang::String.new("Hello World from JRuby!")

puts s

   下面提供了一個示例程式,javaHello.rb,它使用Java的HashMap來存儲三個字元串并且列印它們。這個程式中有趣的地方在于,它調用 Ruby的java.util.Set(通過java.util.HashMap.keySet()方法調用傳回)中的each方法。這允許把通過這個 "each"方法傳回的結果鍵傳遞給相應的代碼塊,然後該代碼塊使用該鍵取得相應的字元串,并且輸出該字元串。

require "java"

module JavaLang

include_package "java.lang"

end

include_class("java.util.HashMap") { |pkg, name| "J" + name }

s = JavaLang::StringBuffer.new("Hello Java World")

puts s.append(", I love JRuby")

m = JHashMap.new()

m.put("java", "Java")

m.put("ruby", "Ruby")

m.put("jruby", "JRuby")

puts m

m.keySet().each { |key| puts m.get(key) }

  下面是當使用JRuby運作它時的輸出結果:

C:/JRuby>jruby javaHello.rb

Hello Java World, I love JRuby

{java=Java, ruby=Ruby, jruby=JRuby}

Java

Ruby

JRuby

C:/JRuby>

  一個完全使用Java編寫的類似上面的程式看起來如下所示:

StringBuffer s = new StringBuffer("Hello Java World");

s.append(", I love JRuby");

HashMap<String> m = new HashMap<String>();

m.put("java", "Java")

m.put("ruby", "Ruby")

m.put("jruby", "JRuby")

for (String key: m.keySet()) {

 println(m.get(key));

}

   七、 在JRuby中使用Swing

  Swing是一個GUI架構,它允許開發者使用Java語言建立圖形化應用程式。下面是一個示例程式,javaSwingHello.rb,它使用Java的Swing來列印一個消息:

require 'java'

include_class "javax.swing.JFrame"

include_class "javax.swing.JLabel"

frame = JFrame.new()

jlabel = JLabel.new("Hello from JRuby with Swing")

frame.getContentPane().add(jlabel)

# frame.content_pane.add(label)

frame.pack()

frame.setVisible(true)

frame.visible = true

  從指令行如下運作這個程式:

C:/JRuby>jruby javaSwingHello.rb

  一個帶有文本"Hello from JRuby with Swing"的新視窗将會出現:

   八、 結論

   本文僅提供一個JRuby語言的簡介。JRuby允許現有Java開發者充分利用Ruby提供的強有力和易于使用的程式設計特點,而Ruby開發者将能夠自 由使用龐大的曾使Java廣泛地應用于各個軟體開發領域的Java庫來進行開發。在歸于Sun麾下之後,JRuby的發展前途一定會更加光明。各位讀者不 妨花一點時間進一步研究一下JRuby,挖掘一下這個工具到底蘊含着多大的能量。