japan.internet.comThe Internet & IT Network
Twitter
RSS
  • ニュース
  • コラム
  • リサーチ
  • ヘッドライン
  • 特集
  • ブログ
  • プレスリリース
  • 専門チャンネル
  • イベント
  • ランキング
  • ニュースメール
2009年11月22日
文字サイズ文字サイズ小文字サイズ中文字サイズ大
事業仕分けによる次世代スーパーコンピューターの開発予算削減について、どうお考えですか?
賛成
反対
どちらとも言えない
投票締切 11/30 12:00
デベロッパー コラム2008年4月8日 10:00
developer.com
developer.com japan.internet.com 編集部(japan.internet.com)メールホームrss
米国 WebMediaBrands が運営する、ソフトウェア開発の専門サイト

JavaとRuby:主要機能の比較

海外海外internet.com発の記事

はじめに

 Rubyはインタプリタによって解釈されるスクリプト言語で、Javaはコンパイラによってコンパイルされるプログラミング言語です。Rubyは、オブジェクト指向言語であり厳密な型指定を行うという点ではJavaに似ています。しかし、Rubyの型指定は動的であるのに対し、Javaの型指定は静的です。Rubyでは型宣言は使用されず、Javaでは型宣言は必須です。JavaとRubyのどちらにも継承があり、"パブリック"、"プライベート"、"プロテクト"のメソッドがあります。RubyはJavaより単純でJavaより高速です。Rubyはさまざまな点でJavaと異なっています。本稿では、RubyとJavaの主要機能を比較します。

インタプリタ方式とコンパイラ方式

 Rubyはインタプリタ方式のスクリプト言語なので、コンパイルしてバイトコードを生成することなく、直接実行できます。たとえば、Rubyファイル「helloruby.rb」は、次のコマンドで実行できます。

>ruby helloruby.rb

 これに対し、Javaアプリケーションは実行前にコンパイルする必要があります。たとえば、Javaクラス「hellojava.java」は、次のコマンドでjavacコンパイラを使ってコンパイルする必要があります。

>javac hellojava.java

 javacコンパイラは、Javaクラスのバイトコードを生成します。その結果、コンパイルしたクラスはjava.exeアプリケーションを使用して実行できるようになります。

>java hellojava

パッケージのインポート

 Rubyでは、requireステートメントを使用してパッケージやモジュールをインポートします。たとえば、extensionsパッケージ/モジュールをインポートするには次のようにします。

require 'extensions'

 外部ファイルをRubyアプリケーションに含めるには、loadまたはrequireを使用します。たとえば、外部ファイル「catalog.rb」を含めるには、次のrequireステートメントを追加します。

require "catalog.rb"

 loadrequireの違いは、loadがメソッド実行のたびに指定のRubyファイルを含めるのに対し、requireはそのRubyファイルを一度だけ含める点です。

 Javaでは、importステートメントを使用してパッケージをロードします。たとえば、Javaパッケージ「java.sql」をロードするには次のようにします。

import java.sql.*;

型付き変数

 RubyでもJavaでも厳密な型指定を行いますが、Rubyの変数の型指定は動的です。これはつまり、変数の型を明示的に関連付けられないということです。たとえば、文字列値を持つ変数は次のように宣言します。

str="Hello Ruby"

 このstr変数には特定の型が関連付けられていないので、整数型その他の型の値を代入できます。

str=1

 Javaの変数の型指定は静的であり、変数に型を関連付けることができます。たとえば、文字列変数は次のように宣言します。

String str="Hello Java";

 このstr変数に整数値を代入することはできません。

null値

 Rubyでは、null値はnilで宣言します。たとえば、変数strnil値を代入するには次のようにします。

str=nil

 Javaでは、null値はnullで宣言します。たとえば、変数strにnull値を代入するには次のようにします。

str=null;

オブジェクト指向

 Rubyでは、数値、変数、メソッドなどすべてがオブジェクトです。Javaでは、クラスのみがオブジェクトになります。たとえば、Class1型のオブジェクトは次のようにして作成します。

Class1 class1=new Class1();

メンバ変数

 Rubyでは、メンバ変数はすべてプライベートです。Javaでは、メンバ変数はデフォルトでパッケージアクセスとなり、publicprivateprotectedの各識別子を使用してパブリック、プライベート、プロテクトとして宣言できます。プライベートメンバにはそのクラス自体の内部からのみアクセスできます。Javaのパブリックメンバには他のどのクラスからもアクセスできます。Javaのプロテクトメンバには、クラスがそのメンバを宣言しているのと同じパッケージの内部およびそのクラスのサブクラスの内部からアクセスできます。Javaのデフォルトパッケージアクセスでは、クラスがそのメンバを宣言しているのと同じパッケージの内部およびそのクラス自体の内部からアクセスできます。

キャスト

 Javaでは、ある条件を満たす場合に、オブジェクトを他のオブジェクトにキャストできます。その条件とは、「キャストしようとするオブジェクトの型が、キャスト先オブジェクトの型の拡張である」というものです。たとえば、LinkedHashSet型のオブジェクトlinkedHashSetHashSet型にキャストできます。LinkedHashSet型はHashSet型の拡張であるためです。

HashSet hashSet=(HashSet)linkedHashSet;

 Rubyでは、変数の型指定が動的に行われ、任意の他の型に代入できるので、キャストは使用しません。

クラスとメソッドの定義

 Rubyでは、クラスとメソッドのブロックをendキーワードで区切ります。Javaでは、クラスとメソッドのブロックを中括弧{}で区切ります。たとえば、RubyでCatalogというクラスを定義するには、class修飾子を使用して次のように記述します。

class Catalog

end

 Rubyのクラス名は先頭を大文字にする必要があります。Javaのクラスも、class修飾子を使用して定義し、名前の先頭を大文字にする必要があります。

class Catalog{
}

 Rubyでは、クラスの宣言にアクセス修飾子は使用しませんが、Javaでは、クラスにpublicアクセス修飾子を指定でき、デフォルトのクラスアクセスはパッケージレベルになります。たとえば、JavaではCatalogというクラスを次のように宣言できます。

public class Catalog{

}

 Rubyのメソッドは、defで開始し、endで終了します。たとえば、getCatalogIdというメソッドを次のように定義できます。

def getCatalogId
  return 1
end

 デフォルトでは、Rubyのメソッドはパブリックです。Rubyのメソッドには、publicprivateprotectedの修飾子を指定できます。Rubyのメソッドでは値を返すことができますが、メソッド定義で戻り値の型は指定しません。Javaのメソッドはデフォルトでパッケージアクセスになり、戻り値の型を指定する必要があります。たとえば、JavaではgetCatalogIdメソッドを次のように宣言できます。

int getCatalogId(){return 1;}

 Javaのメソッドにはpublicprivateprotectedの修飾子を指定できます。Rubyでは、メソッド呼び出しに丸括弧を使用するかどうかは任意です。たとえば、引数nameを受け取ってHelloメッセージを返すhelloというメソッドを定義したとします。

class Hello
  def hello(name)
    return "Hello " +name
  end
end

 このhelloメソッドを呼び出すときに、次のように丸括弧を付けることも付けないこともできます。

helloObj=Hello.new
helloObj.hello("John")
helloObj.hello "John"

 Javaでは、メソッド呼び出しの丸括弧は必須です。たとえば、Helloメッセージを返すhelloというメソッドを定義したとします。

public class Hello{

public String hello(String name){

    return "Hello "+ name;

}

}

 このHelloクラスのhelloメソッドを呼び出すときは、引数を囲む丸括弧を省略できません。

Hello helloObj=new Hello();
helloObj.hello("John");

クラスのコンストラクタ

 Javaでは、クラス名がコンストラクタになります。たとえば、Helloというクラスを定義し、そのクラスのコンストラクタを定義します。

public class Hello{
    String defaultMsg;
    public Hello(String msg){
        defaultMsg=msg;
    }
}

 このコンストラクタは、String型変数defaultMsgの値を設定します。Rubyでは、クラスのインスタンス化はinitialize関数で行います。たとえば、クラスを定義し、そのクラス内で変数をインスタンス化するには、次のようにinitialize関数を使用します。

class Hello
  @defaultMsg
  def initialize(msg)
    @defaultMsg=msg
  end
end

クラスのインスタンス化

 Rubyでは、クラスをインスタンス化するときにクラスメソッドnewを使用します。たとえば、前の例のHelloクラスは次のようにしてインスタンス化できます。

hello=Hello.new("Hello Ruby")

 newメソッドに渡した引数はinitialize関数に渡されます。Javaでは、クラスのインスタンス化にJava演算子newを使用します。

Hello hello=new Hello();

 new演算子は、クラス内で定義したどのコンストラクタにも使用できます。たとえば、String型の引数を受け取りデフォルトのHelloメッセージを設定するコンストラクタがHelloクラスにある場合、このクラスは次のようにしてインスタンス化できます。

Hello hello=new Hello("Hello Java");

 Javaでは複数のコンストラクタを宣言できますが、Rubyのクラスに含めることのできるinitializeメソッドは1つのみです。Rubyで複数のinitializeメソッドを宣言しても例外は発生しませんが、その場合使用されるのは最後のinitializeメソッドのみです。

継承

 JavaでもRubyでも、クラス宣言の際に他のクラスを拡張できます。Javaでは、次のようにextendsキーワードを使用してクラスを拡張します。

public class LinkedHashSet extends HashSet{}

 Rubyでは、<を使用してクラスを拡張します。たとえば、ActiveRecord::Baseクラスを拡張するCatalogクラスを宣言するには次のようにします。

class Catalog < ActiveRecord::Base

end

 RubyでもJavaでも親クラスは1つだけです。Javaでは、抽象メソッドを含む複数のインターフェイスを使用し、各インターフェイスの実装クラスでメソッドを実装するという方法で多重継承を実現できます。Rubyでは、モジュールとmixinによって多重継承が可能になります。

編集部注
 原文では、この後にRubyのモジュールによるmixinの説明がありましたが、説明内容が不正確・不適切と判断したため、割愛しました。

例外処理

 Javaでは、例外をtry-catch-finally構造で処理します。これは、1つのtryブロック、任意の数のcatchブロック、また任意で1つのfinallyブロックで構成されます。tryブロックでは、例外が発生する可能性のあるステートメントを実行します。各catchブロックでそれぞれの例外を処理します。任意のfinallyブロックでは、オブジェクトをクローズするステートメントを実行できます。finallyブロックは、必ずアプリケーションがtryブロックを終了した後に実行します。try-catch-finallyブロックの例を次に示します。ここでは、tryブロックでMySQLデータベースとのConnectionオブジェクトを作成し、catchブロックでSQLExceptionを処理し、finallyブロックでConnectionオブジェクトをクローズしています。

Connection connection = null;

try {
    String url= "jdbc:mysql://localhost:3306/test";
    connection= DriverManager.getConnection(url, "root","");
} catch (SQLException e) {
    System.err.println("Caught: SQLException: " + e.getMessage());
} finally {
    try {
        connection.close();
    } catch (SQLException e) {
    }
}

 Rubyでは、例外はbegin-rescue-ensure-end構造で処理します。この構造は、指定の例外が発生したときに実行するステートメントを含んだ任意の数のrescue句から成ります。任意のensure句は、例外が発生してもしなくても常に実行するステートメントを含みます。Rubyのrescue句はJavaのcatch句に相当し、Rubyのensure句はJavaのfinally句に相当します。begin-rescue-ensure構造の例を次に示します。

begin

rescue RubyException1
  RubyException1が発生したときに実行するステートメント
rescue RubyException2
  RubyException2が発生したときに実行するステートメント
ensure
  例外が発生してもしなくても実行するステートメント
end

まとめ

 RubyはJavaと似ており、Javaと共通の機能もありますが、ONJavaの記事「Ruby the Rival」に書かれているようなJavaの代わりとなる言語ではありません。Java EEが、JavaによるModel-View-Controllerアプリケーション開発向けエンタープライズフレームワークであるように、Ruby on Railsは、RubyのModel-View-Controllerフレームワークです。

著者紹介

Deepak Vohra(Deepak Vohra)
O'Reillyの技術レビュー担当者として『WebLogic: The Definitive Guide』を担当。NuBeanコンサルタント、Web開発者でもある。Sun認定資格(Java 1.4プログラマおよびWebコンポーネントディベロッパJ2EEバージョン)を取得。メールの宛先はdvohra09@yahoo.com。
Graphic Design Forum
【Graphic Design Forum】
流動的媒体と静的媒体に関する見解(11月18日)
「IT の耳」
「IT の耳」
【書評】『Hyper-V スタートアップバイブル』――仮想化についてのすぐれた解説書(11月20日)
百式のネットビジネス研究
百式のネットビジネス研究
世界でもっともパワフルな iPod のスピーカー「Wall of Sound」(11月20日)
週刊-サイト別アクセス状況データ
週刊-サイト別アクセス状況データ
ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(11月19日)
海外ソーシャルウェブに学ぶ成功の秘訣
海外ソーシャルウェブに学ぶ成功の秘訣
ゲーム業界を襲う世界的な激震。ソーシャルゲーム急成長のインパクト(11月19日)
今さら聞けない初歩からのアクセス解析
今さら聞けない初歩からのアクセス解析
サイトリニューアル前のアクセス解析活用法(11月19日)
成約率、反応率を上げる Web 文章術
成約率、反応率を上げる Web 文章術
文章力を磨き、キャッシュを生み出す Web サイト に(11月19日)
「Webからの脅威」―その傾向と最新対策
「Webからの脅威」―その傾向と最新対策
新たな対策技術:スパムフィルタリングと E-mail レピュテーション(11月18日)
ROI向上のための戦略的WebPR
ROI向上のための戦略的WebPR
「戦略的 WebPR」のしかけ方〜WebPR の効果測定手法とは〜(11月18日)
スマートにソーシャルウェブを構築しよう
スマートにソーシャルウェブを構築しよう
社員力を生かすソーシャルメディアポリシー(11月17日)
DevX
DevX
Erlangを使った並列処理プログラムの作成(11月17日)
Copyright 2009 Japan Internet.com K.K. All Rights Reserved.http://www.internet.com/