プログラム・プロブレム

第十回 Java概要(Java)


I はじめに

涼(以下S):今回は Java の概要についてですね。
初(以下H):Web アプリに使われるようになって、一気に広まったような感じがあるな。
S:初期の頃は、あまりの実行速度の遅さに涙が出るくらいだったのに。
H:ハードウェアの進歩は恐ろしいな。

II 特徴

S:さて、まずは分類ですが、強い型付け、コンパイル型、命令型です。
H:C++ がベースになっているが、一部の低レベルな機能をカットしているぞ。
S:そのおかげで、一番問題の多かったメモリ回りのエラーが減りましたね。

H:最大の違いはメモリ管理が自動ガベージコレクションになったので、C 系最大の難関であるポインタ関係の問題が無くなった事だ。
S:NULL ポインタだけは、都合により残っちゃいましたけどね。

H:あとは実行時に動的にプログラム自体にアクセスできる「リフレクション」機能が入っている。
S:始めのうちは関係ありませんが、慣れてくると便利に使えますよ。
H:知らないうちにライブラリが使ってたりもするけどな。

III 簡易文法

条件分岐

01:if( 3 < 4 ) {
02:  System.out.println( "True" );
03:} else if( 0 > 1 ) {
04:  System.out.println( "False" );
05:} else {
06:  System.out.println( "Never executed." );
07:}
S:始めは条件分岐です。Ruby の時と同じですね。
H:やっぱり普通に if 文だな。って言うか、C 系まんまか。
S:そうですね。出力が「System.out.println()」になってますけど。

ループ

01:while( bLoop ) {
02:  # いろいろな処理
03:}
H:次は while ループだぞ。
S:やっぱり C 系と同じですね。
H:言語の設計の際に C++ を元にしたらしいからな。
01:for(int i = 0; i < 5; ++i) {
02:  System.out.println( i );
03:}
S:for ループですね。0~4 が出力されます。
H:同じく C 系のままだ。慣れてるヤツは覚えやすくていいな。

例外

01:try {
02:  throw( new Exception("throwing this string.") );
03:  System.out.println( "not reached." );
04:} catch(Exception e) {
05:  System.out.println( "Exception occured : " + e.getMessage() );
06:} finally {
07:  System.out.println( "finished." );
08:}
S:try-catch-finally になりますね。
H:やってることは前回の Ruby と同じだ。
S:finally があるのが C++ と違うところですね。
H:たまに間違って C++ でも finally を使おうとしてしまうのはご愛嬌だ。

クラス定義

01:class PlusN {
02:  private int m_n;
03:  public PlusN(int n) {
04:    m_n = n;
05:  }
06:  public int getResult(int v) {
07:    return v + m_n;
08:  }
09:  public static void main(String []args) {
10:    PlusN obj = new PlusN(3);
11:    System.out.println( "2 + 3 = " + obj.getResult(2) );
12:  }
13:}
S:クラス定義は01~09行目です。
H:内容は前回と同じだ。C++ と違って、クラス定義内部に直接メンバ関数定義を書くぞ。
S:メンバ関数は宣言だけではダメということですね。
H:後は特に気になる点は… mainかな?
S:それについては次の項で説明しますので、少々お待ちくださいね。
H:すぐ次だから待たないと思うが…

IV 特徴的な言語要素

main エントリポイント

01:class ClassA {
02:  public static void main(String []args) {
03:    // 色々
04:  }
05:}
S:さて、Java ではプログラム自体の main エントリポイントというのは存在しません。
H:その代わりにクラスごとに main メンバ関数(メソッド)を作っておける。
S:実行時に開始クラス名を指定して、そのクラスの main メソッドから実行が開始されるんです。
H:だから、この他に ClassB も有ってそっちも main を持っているかもしれない。
S:実行時に ClassA か ClassB のどちらかの main を指定して開始することになるわけですね。

リフレクション

01:public class MainClass {
02:    public static void main(String []args) {
03:        try {
04:            Class clazz = Class.forName("SampleClass");
05:            if (clazz != null) {
06:                SampleClass obj = (SampleClass)clazz.newInstance();
07:                obj.hello();
08:            }
09:        } catch (Exception e) {
10:            e.printStackTrace();
11:        }
12:    }
13:}
14:
15:class SampleClass {
16:    public void hello() {
17:        System.out.println("Hello World!");
18:    }
19:}
H:さて、リフレクション機能の例なんだが…
S:あんまり実感わかないかもしれませんね。
H:「クラス定義」の項の10、11行目の(main関数の)内容を04~07行目でやってるわけです。
S:04~06行目が、本来は「SampleClass obj = new SampleClass();」となるはずなんですよ。
H:それで出来たオブジェクト obj に対して hello() メソッドを呼ぶわけだな。
S:その部分を、文字列のクラス名から実際のオブジェクトにしちゃってる仕組みなんです。
H:クッキーだと「星型」っていう文字列に「お前の形のクッキーを新しく作れ」と言ってることになるな。
S:またクッキーの例ですか… しかも、その説明って相当無茶なこと言ってますよ。
H:確かに「文字列に命令」ってのは実際は無理だが… 概念としては合ってるはずだ。
S:とりあえずクッキーの件は置いておくとして、何が嬉しいかというとプログラムの動作中に文字列を(キーボード入力などから)渡して、その指示で作るオブジェクトを選べることです。
H:たとえてみると、機能無しだと工場で決まった形のクッキーしか作れないが、この機能のおかげで工場の始動時に形を指定できるわけだ。
S:またクッキー… 無視よ、無視… さて、コンパイラ型言語でリフレクション機能を持っているのは結構珍しいんです。
H:スクリプト言語とかだと、インタプリタや弱い型のおかげなのか、よく見かけるんだがな。

V 終わりに

S:特徴の説明が少ないんですが、標準ライブラリが豊富なので使える機能はとても多いです。
H:ベター C++ な感じだな。性能要求が厳しくなければ選択肢としてはいいと思う。
S:あと、携帯みたいなモバイルプラットフォームでも開発環境の整備が進んでますね。
H:これから覚えたい言語の中では上位にラインナップされるかね。
S:ちなみに毎度のことながら、詳細は他サイトをご参照くださいとのことです。
H:以上だ。またそのうち。

第十回 終了


一覧に戻る