Java/ecb

Last-modified: 2010-10-15 (金) 15:55:32

あいまいになっている個所の確認。

  • 静的メソッド
  • 静的ブロック
     ⇒そのクラスが使用される直前に呼び出されるブロック
     static { ... }
  • メンバ変数は初期化されているが、ローカル変数は初期化されていない
  • javaではC++のdeleteに相当するものはない。
     ⇒使い終わった場合は、使い終わったことを示すためにnullを代入する。
     ⇒ガーベージコレクタ任せ
  • 配列の.lengthは便利なので使うべし

instanceofの使用例

 ポリモーフィズムを実装したはいいが、長方形と円の面積を別々に出したいときに、
 instanceofでCIRCLEクラスとRECTクラスを判別するとよい。

パッケージの作り方や例外

 1.宣言するときは、クラスごとにpackage XXXと書く。
  (違うファイルでもpackage XXXとかけば同じパッケージ)
 2.import XXX.*と書いて、すべてのクラスをインポート
 3.classpathとは、packageのフォルダを登録するパスのこと
 4.パッケージとフォルダ名はあわせる

予期せぬエラー終了の見方

 予期せぬエラーが発生するとJavaではそのスレッドが終了してしまう。
 (単一スレッドのときはプログラムが終了する)

 Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.average(Test.java:20)
at Test.main(Test.java:12)

 Exception in thread "main"
 とは、"main"のスレッドでExceptionが例外発生したことを表す

 「java.lang.ArithmeticException: / by zero」が例外の内容をあらわしていて、
 次の行からどの部分で例がが起こったかをあらわしている。
 Test.javaの20行目、Testクラスのaverageメソッドで起こっていて、
 Test.averageメソッドはTest.javaの12行目(Testクラスのmainメソッド)から
 呼び出されていることがわかる。

例外

try{...}catch(...){...}catch(...){...}finally{...}

 で、finallyの部分は例外が発生してもしなくても実行される部分である。省
略可。
 try中で例外が発生した部分より下のコードは実行されない。
 catchブロックは1つ以上必要。
 代表的な例外の例:http://www5c.biglobe.ne.jp/~ecb/java/11_03.html

try{...}catch{...}で、catchに対応する例外をキャッチする部分がなかった場合、

 呼び出し側のtry{...}catch{...}のcatchの部分を見に行く。

例外もクラスの1つで、継承関係がある。

 また、catchブロックは上から実行され、1度の例外に対して1回しかキャッチされないため、
 サブクラスを上に記述しなければならない(※コンパイルエラーになる⇒catch not reached)

throwは例外を呼び出し元のキャッチブロックにも受け取らせるための処理

 (「例外を上に投げる」と呼んでいる)
 throw eだけでなく、throw new ArrayIndexOutOfBoundsException();
 などプログラマが明示的に投げることもできる。
 ただし、投げることができるのはThrowableクラスのサブクラスだけ
 (Stringクラスなどは投げられない)

public static int a(int array[], int i) throws

ArrayIndexOutOfBoundsException{
 のように、例外を投げる可能性のあるメソッドを作成したときには、
 わかりやすさのために、throwsステートメントを記述することがある。
 必須ではないが、推奨。

Exceptionクラスを継承して独自の例外クラスを作成することも可能

 必ずキャッチするか、throuwsステートメントで独自の例外を投げる
 可能性があることを明示しなければならない。
 ただし、独自の例外がRuntimeExceptionのサブクラスの場合は、この制限は適
用されない。

エラーと例外

 ThrowableクラスにはErrorクラスとExceptionクラスがある。
 予測できるエラーは例外として処理で、
 プログラマやユーザーのせいではないJVMの重大なエラーをエラークラスと呼んでいる

スレッドの作り方

 1.Threadクラスを継承
 2.runメソッドをオーバーライド
 3.Threadクラスのstartメソッドを呼び出す

 join()でスレッドの終了まで待機できる。
 スレッドセーフにする(ロックする)場合は、メソッドの前にsynchronizedを設定する

 また、synchronized( インスタンス名 ){ ... }処理とすると、
 オブジェクトにロックをかけて、synchronizedのついたブロック内がスレッドセーフ

 スレッド間の通信として、他のスレッドがnotifyを出すまで待つ場合はwaitを設定
 他のスレッドに制御を与える場合はnotifyまたはnotifyAllを実行
 notifyは1つだけwaitしているスレッドに通知するが、
 どのスレッドに通知されるかはJVMが勝手に決める
 ※他にもPipedOutputStream, PipedInputStreamを使った方法もある。

ガーベージコレクタの呼び出し(?)

 携帯電話など比較的リソースの乏しいプラットフォームでJavaを実行する場合は、
 メモリーをできるだけケチって使いたい場合がある。
 このような場合、ガーベージコレクトをJVMに任せていてはメモリーが足りな
くなる。

 もちろんメモリーを使用したい時に残りのメモリーが足りなくなれば
 JVMはガーベージコレクターを起動させるが、
 もし、時間的に余裕がない時に実行されてしまっては困る。

 そこで、ガーベージコレクタに動作するようお願いするときは
 Systemクラスのgc()メソッドを使用する。

 ※ただし、ガーベージコレクタを実行してほしいとJVMにお願いするだけで、
  すぐに実行されるとは限らない。ガーベージコレクタを実行するという解説も
  よくみられるが誤り。

 Objectクラスのfinalizeメソッド(オーバーライド用)は、メモリが解放され
る前に
 ガーベージコレクタによって呼び出されるメソッド。
 finalizeもいつ呼び出されるかは不明だが、SystemクラスのrunFinalizeメ
ソッドで
 実行を促すことができる(ただし必ずではない)
 cf: finally = catchで必ず実行されるブロック
 cf: final = 継承禁止forクラス, オーバーライド禁止forメソッド,変更禁止
forメンバ変数

色々なクラス

  • Mathクラスにはmax,min、など便利機能がついている
  • Vectorは可変長の配列(ただし、格納できるのはクラスのインスタンスと配列
    のみ。
    char型を入れたいときはCharacter型に変える)
     .addElementで追加して、配列のサイズを自動で+1する
     
  • スタックはStackクラスでサポートされている
  • 連想配列はHashtableクラス
  • Enumerationインターフェースを使うと、VectorやHashtableに格納されている
    データを
     最初から最後まで次々とアクセスできる
  • Stringは+で結合できるが、文字列の長さが頻繁に変わる結合は処理時間がかかる
     この場合にはStringBufferクラスを用いる
     C言語と違い、2バイト文字もJavaでは1文字とみなす。
  • StringTokenizer(ストリングトークナイザ)は、
     Stringの文字を改行やタブなどで切り分けたりできる。
  • DateクラスやCalenderクラスは使いそうなので覚えておく。

シリアライズ

 クラスオブジェクトのデータをストリームから入出力できるようにすることをシリアライズ(直列化)という。
 基本的にクラスオブジェクトのシリアライズは
 そのクラス内のメンバー変数すべてを出力するが、足りない場合はクラス内に定義する。
 また、シリアライズに対応していることを明示するために
 Serializableインターフェースをインプリメントする

 このようにしたクラスはそのオブジェクトをObjectOutputStreamで出力し、
 ObjectInputStreamで入力することができる。
 つまり、ディスク上に保存したり、別のスレッドに転送したり、ネットワークを経由して
 転送したりできるようになる。(実は、当時、見てもよくわからなかったが、ネットワークには重要そう?)

Webサーバーへの複数クライアント接続法

 サーバーは通常、複数のクライアントからアクセスされる。
 したがって通常のフローだと、1つのクライアントが接続したら、
 次のクライアントは接続できなくなってしまう。
 
 このような場合は、クライアントが接続されたら新しくスレッドを立ち上げ、
 新しいスレッドで通信を開始し、自分のスレッドはすぐに次のクライアントに
 向けてアクセスを待ちに行くようにする。

アダプタクラスとは

 たとえば、マウスの動きを監視したい場合MouseListenerや
 MouseMotionListenerを使う。
 しかし、MouseListenerは5つもメソッドを実装しなければならないため大変
 (実際はマウスがクリックされたmouseClickedメソッドや
  ボタンが放されたmouseReleasedメソッドくらいしか使わない)
 それなのに5つのメソッドを実装するのは面倒。
 そこで用いられるのがアダプタクラスというもの。継承して使う

無名クラス

 Adapterを使うより、さらに短くて済むのは無名クラス。
 newと同時に直後に{...}で括り、その中にメソッドを実装する。
 ただし、見にくくなるので、
 無名クラス内は、他のメソッドを呼び出すだけという記述を心がけるべし。

アプレットのロード

 アプレットが、複数のクラスファイルからできているプログラムの場合、
 一番最初はhtmlファイルの<Applet>タグで指定されたクラスしかロードしない。

 実際に別のクラスファイルを読み込む必要ができた場合に、
 そのクラスファイルがダウンロードされるので、
 ネットワークが遅い場合などはプログラムが一時停止したようになる。
 ⇒ これをさけるためにJarファイルというものを使うとよい

jarファイルについて

 圧縮ファイル。zipファイルという圧縮ファイルとほぼ同じフォーマット

zipとjarの違い

 zipファイルとjarファイルは何が違うかというと、
 jarでは悪意あるプログラムが入っていないと言うことを署名する
 マニフェストを埋め込むことが可能。

 有効なマニフェストが含まれていると、他のサーバーと通信できないと行った
 JavaAppletの制限を取り除くことも可能

Appletからjarを指定する方法

 TestAppletクラスはtest.jarに格納されている場合は下記のように記述
 <applet code="TestApplet" archive="test.jar" width=300 height=100>
 <param name="COLOR" value="FF00CC">
 </applet>

 他にもサブフォルダを指定したり、jarの代わりにzipを指定したりも可能
 http://www5c.biglobe.ne.jp/~ecb/java/19_09.html

アプレットへの引数渡し

 通常のJavaプログラムでは、プログラムの引数(コマンドラインからの引数)
 をStringの配列として渡すことができた。
 アプレットも<applet>と</applet>の間に<param>タグを挿入することで、
 引数を渡すことができる。

 アプレットへの引数はコマンドラインからの引数のように単なる文字列を
 渡すのではなく、引数の名前とその値の両方を渡す。
 下の例では、COLORという名前の引数の値として"FF00CC"を与えている。

 <applet code="TestApplet" width=300 height=100>
 <param name="COLOR" value="FF00CC">
 </applet>

 これをプログラムで取得するためには、AppletクラスのgetParameterメソッド
 を使用する

javadoc

 javadocというJavaのリファレンスマニュアルを
 自動で作成するものがあるらしい
 (doxygenのようなものか?明日調査予定)
  →eclipseのメニューにもあるが、普通にdoxygenでいいやと思うようになった
   印象としては、javadoc ⊂ doxygenといった感じ

 http://www.tohoho-web.com/java/index.htm