Back To Main


┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┃ ◆Javaで珈琲ブレイク vol.004, 005 番外編◆
┃……………………………………………………………………………………………
┃ [不定期] まぐまぐ ID=0000088576 Melma! ID=m00061296
┃……………………………………………………………………………………………
┃ 今回からご覧になる方は、バックナンバーもご活用下さい
┃ http://www.melma.com/mag/96/m00061296/
┃ http://backno.mag2.com/reader/Back?id=0000088576
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


皆さん、こんにちは。

Mr.Hackです。

この号はvol.004,005の番外編です。メルマガは一回に送れる字数制限があるので、入りきらなかった豆知識・サンプルコードをお届けします。


vol.005で、皆さんがfinallyを実感してもらえるように、簡単なプログラムを書きました。CPadでコンパイル・実行してみてください。

【ExceptionTest.java】
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* Try Catch構文とFinally節のテスト
*
* @author Mr.Hack
*/
public class ExceptionTest {
/**
* indexの5番目にアクセスしているため(通常インデックスは、
* 0から始まるため、最後は4)、IndexOutOfBoundsExcptionの例外発生。
* プログラム終了前に、Finally節が実行されるので、プリント結果は、
* "エラー1:catch節内"、"エラー2:finally節内"
*
* @param args コマンドライン引数
*/
public static void main(String[] args) {
int[] integers = new int[5]; //int型配列、要素数5
int integer = 0;

try {
integer = integers[5]; //インデックス6番目にアクセス
}
catch (IndexOutOfBoundsException e) {
System.out.println("エラー1:catch節内");
return;
}
finally {
System.out.println("エラー2:finally節内");
}
System.out.println("このprintln()メソッドは実行されず");
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━

以下の豆知識は、vol.004で収録しきれなかったものです。vol.004のスーパークラスであるObjectクラスの話のなかのtoString()メソッドをご覧いただきながら、豆知識をご覧下さい。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
◆豆知識◆ toString()メソッド
────────────────────────────────────

Objectクラスのメソッドは全てのクラスに継承されます。そのため、vol.002の【HelloWorldDemo1.java】でも定義なしで使うことができます。ただし、APIでObjectクラスのtoString()メソッドのリンクをクリックして詳細を見てもわかるように、

------------------------------------------------------------------------
すべてのサブクラスで、このメソッドをオーバーライドすることをお勧めします。
------------------------------------------------------------------------

となっています。そうしないと、

------------------------------------------------------------------------
Object クラスの toString メソッドは、オブジェクトの派生元のクラス名、アットマーク (@)、およびオブジェクトのハッシュコードの符号なし 16 進表現から構成される文字列を 返します。つまり、このメソッドは次の値と等しい文字列を返します。
------------------------------------------------------------------------

ということです。どういうことかと言いますと、例えば、PrintStreamクラスのprintln()メソッドを各クラスでオーバーライド(ニュアンス的には、上書き)しないと、訳のわからな文字列が表示されます。試しにその訳のわからない文字列を表示してみましょう。APIのObjectのtoString()の詳細に

------------------------------------------------------------------------
オブジェクトの文字列表現を返します。
------------------------------------------------------------------------


とあるように、オブジェクトの文字列を戻り値としてかえすので

System.out.println(MyClass)とすることができますね。vol.002で登場したHelloWorld.javaはそのままで使い、HelloWorldDemoの

System.out.println(myClass.getMessage());

System.out.println(myClass);

と変えてみましょう。

【HelloWorld.java】
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* HelloWorldクラス
* "ハローワールド"の文字列を含む
*
* @author Mr.Hack
*/
class HelloWorld {

/** メッセージを含む文字列変数 */
String message;

/**
* コンストラクター messageフィールドをハローワールドで初期化
*/
HelloWorld() {
this.message = new String("ハローワールド");
}

/**
* message変数を得る
*
* @return message メッセージを含む文字列変数
*/
String getMessage() {
return this.message;
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━


【ToStringDemo.java】
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* toString()メソッドの機能を使った
* ハローワールドプログラム
*
* @author Mr.Hack
*/
class ToStringDemo {

/**
* ハローワールドとプリントする
*/
public static void main(String[] args) {
HelloWorld myClass = new HelloWorld();
//myClass.getMessage()メソッドの代わりに
//myClassオブジェクトをpassする
System.out.println(myClass);
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━

ToStringDemo.javaをコンパイルし実行すると、

HelloWorldToString@6ec612

というようなメッセージが出てきます。これが、訳のわからない文字列です。でも、コンパイル時に、メソッドがないと

シンボルを解釈処理できません。

と出てきますが、それが出てきませんでしたね。これは、HelloWorldToStringクラスが、toString()メソッドを継承していることを意味します。toString()メソッドをオーバーライドして、

String toString() {
return this.message;
}

としてみましょう。そうすると、HelloWorldToStringのオブジェクトmyClassにtoSting()と適用しても、myClassのままでも、

"ハローワールド"と表示されます。

というのは、toStringはオブジェクトの文字列を戻り値として返すからです。

以上のように、toString()メソッドはObjectクラスのメソッドであることにより、HelloWorldやHelloWorldToStringでも、継承されるのです。


【HelloWorldToString.java】
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* toString()メソッドをオーバーライド
*
* @author Mr.Hack
*/
class HelloWorldToString {

/** メッセージを含む文字列変数 */
String message;

/**
* コンストラクター messageフィールドをハローワールドで初期化
*/
HelloWorldToString() {
this.message = new String("ハローワールド");
}

/**
* message変数を得る
*
*@return message メッセージを含む文字列変数
*/
String getMessage() {
return this.message;
}

/**
* HelloWorldToStringのオブジェクトの
* 文字列を返す。
*
* @return message メッセージを含む文字列変数をオブジェクト
* として返す。
*/
public String toString() {
return this.message;
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━

【ToStringDemo.java】
━━━━━━━━━━━━ ここから ━━━━━━━━━━━━━━━━━━
/**
* toString()メソッドの機能を使った、
* ハローワールドプログラム
*
* @author Mr.Hack
*/
class ToStringDemo {

/**
* ハローワールドとプリントする
*/
public static void main(String[] arg) {
HelloWorldToString myClass = new HelloWorldToString();
//myClass.getMessage()メソッドの代わりに
//myClassオブジェクトをpassする
System.out.println(myClass);
//myClassにtoStirngを適用
System.out.println(myClass.toString());
}
}
━━━━━━━━━━━━ ここまで ━━━━━━━━━━━━━━━━━━

"ハローワールド"と表示されましたか?

────────────────────────────────────
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

========================================================================
◆豆知識◆ Type Conversion(型変換)、または、Casts (キャスト)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

vol.004の宿題の解答では、72と華氏を打って、22.2222..と摂氏を得ましたが、72ってdouble型なのでしょうか?

上記の例では、72はparseDouble()メソッドで、double型の変数にアサイン(代入)される時にdouble型になります。入力されたときは、String型の72です。parseDouble()メソッドでint型72がdouble型の72.0にキャスト(cast、型変換)されます。これは、

double doubleNumber = 7;

としたのと同じことです。7はデフォルトではint型です。int型(32bits)からdouble型(64bits)のようなwiden conversion(日本語的には、拡張型変換)は、そのまま代入できます。なぜなら大は小を兼ねるからです。上記の場合、7という小数点以下を含まない数字は、double型へは自動的にキャストされます。つまり、上の例では、doubleNumberは7.0を含んでいます。逆の場合はどうでしょう?

int integerNumber = 7.0; //コンパイルエラー

はコンパイルエラーになります。フローティングポイント(小数点付き)はデフォルトでは、double型ですので、7.0はdouble型です。それをint型に型変換(キャスト)するには、明示的に型を示してあげなければなりません。

int integerNumber = (int) 7.0;

(int)は7.0はint型に変換しますよ、ということを意味します。もう一つおまけですが、booleanタイプへ、または、からの型変換はできません。たとえば、

boolean myBoolean = 1; //コンパイルエラー
boolean myBoolean = (true) 1; //コンパイルエラー
int integerNumber = (int) true;//コンパイルエラー

いずれも、コンパイルエラーになります。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++========================================================================

========================================================================
◆豆知識◆ Java2 SDK1.3.1 ソースコード
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

vol.004では、APIの裏付けとして、実際にコンパイルされてバイトコード(byte code)になっているクラスファイル(拡張子がclass)を見ました。

でも、実際にプロフェッショナル人が作ったSDK APIのコードは見れないのでしょうか?

実は、見れるのです。もう一度、Java2 SDKをインストールしたフォルダに行ってください。デフォルトでインストールした方は、

C:\jdk1.3.1_02

です。そのフォルダに、src.jarというjarファイルがあります。それです。もう前回でjarファイルの解凍の仕方は分かりましたね。解凍してみましょう。ファイルサイズが、19Mもあるので、解凍には結構時間がかかります。息抜きに珈琲をどうぞ。

さて、解凍すると、どうですか?前回見たtr.jarの中身とほぼ同じでしょう。例えば、例外が発生した、DoubleクラスのparseDouble()メソッドを見つけてみましょう。例外発生時には、

at java.lang.Double.parseDouble(Double.java:184)

とありました。階層をjava→langとたどっていくと、Double.javaというファイルがあると思います。それを、CPadで開いてください。ながーいDouble.javaの中身が見れましたね。どうやって、どこをさがしますか?そう、上記の184ですね。これは行ナンバーです。CPadは便利な機能『指定行へジャンプ』があります。プルダウンメニューの検索から、『指定行へジャンプ』を選び、行ナンバーを184と入れて移動ボタンをします。ちなみに、なれてくるとショートカットキーを利用すると便利です。たとえば、『指定行へジャンプ』はCtrl + Gです。メニューを開かずに、CPadのウインドウがアクティブになっているのを確認しCtrl + Gを押してみてください。どうです?便利でしょ。

指定行を指定しジャンプすると、

public static double parseDouble(String s) throws NumberFormatException {
return FloatingDecimal.readJavaFormatString(s).doubleValue();
}

とありますね。NumberFormatExceptionをスローしています。このようにして、実際のソースファイルを閲覧することができます。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
========================================================================

それでは、またあいましょう。Have a nice day!

Mr.Hack

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
◆Javaで珈琲ブレイク◆
────────────────────────────────────
皆様からの激励・批判のメールをお待ちしております。
【発行者】 Mr.Hack - javacafebreak@hotmail.com
【掲示板】 http://fweb.midi.co.jp/~romanhikou/cafe_entrance.html
※質問は上記の掲示板からどうぞ。
【サイト】 http://mrhack.hoops.ne.jp/
【発行数】 まぐまぐ[810] Melma[108]
【解除】http://mrhack.hoops.ne.jp/
※解除は上記のサイトからいつでもできます。
────────────────────────────────────
(c)2002 MR.HACK ALL RIGHTS RESERVED
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


© 2002 MR.HACK ALL RIGHTS RESERVED