読書会(Javaの格言)第3回議事録

[ 戻る ]


< 読書会(Javaの格言)第3回議事録 >

                                                          2000/08/31
                                                          文責 小川直人

□ 日時 : 2000/08/26 (土) 10:00から17:00まで

□ 場所 : Orangesoftさんの会議室

□ 参加者 : 遠藤さん、高橋(智)さん、高橋(知)さん、野村さん、
              西海さん、塩田さん、石黒さん、高岡さん、小川

□ 当日のスケジュール
   1. 自己紹介
   2. 書記,読み手の選出
   3. 読書
   4. 昼食
   5. 読書
   6. 宴会(有志の方)

□ 第7章 クラスのロードとオブジェクト生成

「序論」

◇実行時に動的にクラスをロードする例

 JDBCドライバのロード

「クラスのロード」

◇(p.157)クラスのロードを強制的に行う方法

 forName()を用いる方法

  Class cl = Class.forName("java.lang.String");

 .classを用いる方法

  Class cl = java.lang.String.class;

  前者の方法は,コンパイル時にクラスがクラスパス上
になくてもかまわない.後者の方法は,コンパイル時に
クラスパス上にないとエラーになる.

 (参考)前者の方法はtry文の中に記述する必要がある.
 (例)test35.java,test36.java

「オブジェクトの生成」

◇(p.161)BoundedPlacedShape クラスのコードに誤植

  誤 private Consraints constraints_;
  正 private Constraints constraints_;

◇(p.159)コンストラクタ中のthisとsuper

  thisとsuperを両方とも使用したい場合はprivateな
  ヘルパーメソッドを利用する

  p.159の例においてthis(1,1)の代わりにplacedShped(1,1)と
  書く事はできないか?
   →できない.
  (例)test34.java


◇(p.163)抽象クラスのコンストラクタの良くない使い方

  レーザー射撃ゲームの処理
  1.MovingTargetのコンストラクタから暗黙にsuper()が呼出,
  2.抽象クラスMoverのコンストラクタから抽象メソッドadvance()の呼出
  3.実装したMovingTargetのメソッドadvance()の実行

  抽象クラスはコンストラクタから抽象メソッドを決して呼び出してはいけない.

   →抽象クラスでコンストラクタを書くことはあるのだろうか?
   →なぜ「決して」ダメなのか?

  一般的に,コンストラクタが終了する前にいろいろと処理を
  おこなってしまうのは良くない
   →他人に見せないコーディングではやってしまいがち

  アプレットのコンストラクタで描画をしても何も起こらない

「動的クラスローディング」

◇(p.168)KlingonTranslator

  スタートレックねた

◇(p.169)plug&playは動的クラスローディングの一例

  文字列指定でクラスをロードする方法はパターンではない
  との議論がジャバハウスにあった

「オブジェクトとクラスの使用」

◇(p.171)invokenonvirtualとinvokevirtual

  メソッドがfinalとして宣言されている場合は
  invokenonvirtualバイトコード命令が生成される
 
  パラメータの実行時型をコンパイル時に確定できない
  場合はinvokevirtualバイトコード命令が生成される

   →JVMの仕様は以前の読書会で勉強しました.

   (参考)
   「invokevirtualで呼び出すメソッドはすべて,動的束縛です.
  同一のメッセージパッシングによって,どのメソッド実体が
  呼び出されるかは,変数にバインドされているインスタンスに
  依存するので,実行時にしかメソッド選択をおこなえないよう
  なメソッド呼出です.」(JavaバーチャルマシーンP.166より)
  (例)test37.java,test38.java

「finalize」

◇規則はあるが,原則・ヒントが記述がない

◇finalizeをしない場合

  コネクションを切りたくない時


□お昼休み


□ 第8章 生成に関するイディオム

「Factoryメソッド」

◇(p.183-189)コンテンツサーバ

  利用側のコードはContentServerとNodeのみを使用している.
  NodeやServerが増えても利用側のコードは変更する必要がない.

  VideoServerクラスでvideoNodeを生成しても良いのでは?
   →テスターを書きなおす必要あり.

◇(p.183)インターフェースはコンストラクタ持つことはできない.

  (例)test39.java

「Abstract Factory」

◇(p.190)Abstract Factory

  抽象工場と訳している本がある.
  →その本はdispatchをたらい回しという訳語をつけている.

◇(p.190-202)翻訳システムの例

  結局はinitファイルを作成しろということか?

◇(p.200)AbFactTest

  サポートするすべての言語の訳が出力される

「Singleton」

  Singletonは,本来は,インスタンスの数を制限するパターン.
  

◇Singletonの使い道

  DBのコネクションの数を制限する.
  corbaオブジェクトが一つのみ
  メニュープログラムが一つのみ

◇singletonの意味
  
  1枚札,スコッチウィスキーの銘柄,要素が一つしかない集合

  (参考)英辞郎より
        Singleton
         【人名】シングルトン
         【地名】シングルトン
           ◆【補足】オーストラリア
       singleton
         【名】一枚札、一つづつ起こるもの、別物

◇C++とのコーディングの相違

  C++ではstatic初期化の順序に保証がないので,
  インスタンスを生成するメソッドで,参照がnullかどうか
  チェックをするコーディングが必用となる.
   →これは怠惰なオブジェクトの生成方法
   →九章「怠惰なインスタンス化」p224-225参照

「「仮想」コンストラクタ」

  Employee e = new FatCatEcmplyee( ... );
  Employee e2 = new LowPaidEcmplyee( ... );

   を,コンストラクタを仮想化して

  Emplyee e = new CompanyEmplyee(/* param */);

  と書く.

  CompanyEmplyeeのインスタンスを通して処理をFatCatEcmplyee
  または,LowPaidEcmplyeeに委譲している

□ 第9章 パフォーマンスとリソースとのバランス

「怠惰なインスタンス化」

◇(p.221)MyFrameクラス

  public final class MyFrame extends Frame
  のfinalになにか意味があるのだろうか?

「意欲的なインスタンス化」

  この節で1番言いたいことは,効果的にスレッドを使え,ということ?

◇(p.228)金曜の夜の最初の一杯のビール

  何かの引用なのだろうか?

◇(p.233)CompletionCallbackを実装したClientクラス

  何らかのアクションの実装が欲しいところ.

「怠惰な評価」

◇&&,||を利用した条件判定

  p.237のif文
  if( read_messages && (num_items = mailbag.countItems())>0 ) ....
  読書会参加者の中では,
  このようなコーディングをする(好む)方
  このようなコーディングをしない(好まない)方
  両方いらっしゃいました.

◇(p.239)Chartクラス

  dirtyフラグはどこでクリアしているのか?
   →キャッシュされている結果を表示した後にクリアするはず.

「意欲的な評価」

◇(p.241)LightButtonクラス

  普通このようなコーディングはしないと思う
   →例を無理やり作った感じがする.
   →プロファイラを使って調べたらしいが,ホントだろうか?

  canvasをextendsしてlightweightなボタンを作ろうとしている.
   →普通はcomponentを継承するはす.


□ 雑談の話題

  ・サーブレットの良い本は何?

  ・使いやすいサーブレットエンジンは?

  ・次期の読書会で読む本の候補は?

□ おわりに

 読み手の野村さん,高橋(智)さんお疲れ様でした.
 また,塩田さんには,会議室の手配をしていただき,
 ありがとうございました.
 
 有意義な読書の時間を持つ事ができました.
 参加者の皆さん,ありがとうございました.

◇◇◇◇◇◇◇◇◇◇(例)◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇

//-----------------test34.java------------------//
class test34 {

 void
t34(){ 
  System.out.println("test34()");
 }//end of constructor

 test34(int i){
  test34();
//  this();
  System.out.println("test34(int i)");
 }//end of constructor

    public static void main(String[] args) {
  new test34(5);
 }//end of main

}//end of test34
/*----コンパイル・実行結果-----

C:\My Documents\Java\java_Exa\sample>javac test34.java
test34.java:13: メソッド test34() は class test34 で見つかりません。
                test34();
                      ^
エラー 1 個
*/
//-------------test34終わり----------------//

//-----------------test35.java------------------//
class test35 {

 test35(){ }//end of constructor

 void aMethod(){
  Class cl = javax.servlet.GenericServlet.class;
 }//end of aMethod()

    public static void main(String[] args) {
  new test35().aMethod();
 } file://end of main

}//end of test35

/*----コンパイル・実行結果-----
C:\My Documents\Java\java_Exa\sample>javac test35.java
test35.java:11: クラス javax.servlet.GenericServlet が見つかりません。
                Class cl = javax.servlet.GenericServlet.class;
                                        ^
エラー 1 個

C:\My Documents\Java\java_Exa\sample>set classpath=d:\jsdk2.1\servlet.jar

C:\My Documents\Java\java_Exa\sample>javac test35.java
*/

/*----コメント-----------------
一回目はコンパイルエラー
そこで,servlet.jarにクラスパスを通す.
二回目はコンパイル成功.
*/


//-------------test35終わり----------------//

//-----------------test36.java------------------//
class test36 {

 test36(){ }//end of constructor

 void aMethod(){
  try{
   Sys
tem.out.println( "javax.servlet.GenericServletクラスのロード前" );
   Class cl = Class.forName("javax.servlet.GenericServlet");
   System.out.println( "javax.servlet.GenericServletクラスのロード後" );
  }catch(Exception e){
   System.out.println( "javax.servlet.GenericServletクラスのロード時に例外発

生" );
   System.out.println( e );
  }
 }//end of aMethod()

    public static void main(String[] args) {
  new test36().aMethod();
 } file://end of main

}//end of test36

/*----コンパイル・実行結果-----
C:\My Documents\Java\java_Exa\sample>java  test36
javax.servlet.GenericServletクラスのロード前
javax.servlet.GenericServletクラスのロード時に例外発生
java.lang.ClassNotFoundException: javax.servlet.GenericServlet

C:\My Documents\Java\java_Exa\sample>set
classpath=c:\mydocu~1\java\java_exa\sam
ple;d:\jsdk2.1\servlet.jar

C:\My Documents\Java\java_Exa\sample>java  test36
javax.servlet.GenericServletクラスのロード前
javax.servlet.GenericServletクラスのロード後
*/
/*----コメント-----------------
一回目の実行で例外発生
そこで,servlet.jarにクラスパスを通す
二回目は実行成功
*/

//-------------test36終わり----------------//

//-----------------test37.java------------------//
class test37 {

 void aMethod(){
  System.out.println("Hello invokevirtual!");
 }

    public static void main(String[] args) {
  new test37().aMethod();
 }

}
/*----コンパイル・実行結果-----
C:\My Documents\Java\java_Exa\sample>javac test37.java

C:\My Documents\Java\java_Exa\sample>javap -c test37 >test37.txt
*/
/*----コメント-----------------
test37.txt

Compiled from test37.java
class test37 extends java.lang.Object {
    test37();
    void aMethod();
    public static void main(java.lang.String[]);
}

Method test37()
   0 aload_0
   1 invokespecial #6 
   4 return

Method void aMethod()
   0 getstatic #9 
   3 ldc #1 
   5 invokevirtual #10 
   8 return

Method void main(java.lang.String[])
   0 new #5 
   3 dup
   4 invokespecial #7 
   7 invokevirtual #8 
  10 return


*/

//-------------test37終わり----------------//

//-----------------test38.java------------------//
class test38 {

 final void aMethod(){
  System.out.println("Hello invokenonvirtual!");
 }

    public static void main(String[] args) {
  test38 t = new test38();
  t.aMethod();
 }

}
/*----コンパイル・実行結果-----
C:\My Documents\Java\java_Exa\sample>javac test38.java

C:\My Documents\Java\java_Exa\sample>javap -c test38 >test38.txt

*/
/*----コメント-----------------
test38.txt

Compiled from test38.java
class test38 extends java.lang.Object {
    test38();
    final void aMethod();
    public static void main(java.lang.String[]);
}

Method test38()
   0 aload_0
   1 invokespecial #6 
   4 return

Method void aMethod()
   0 getstatic #9 
   3 ldc #1 
   5 invokevirtual #10 
   8 return

Method void main(java.lang.String[])
   0 new #5 
   3 dup
   4 invokespecial #7 
   7 astore_1
   8 aload_1
   9 invokevirtual #8 
  12 return

*/
invokenonvirtualにならないようです.
//-------------test38終わり----------------//

//-----------------test39.java------------------//
interface test39 {


t39(){ 
  System.out.println("コンストラクタ?");
 }
 void aMethod();

}
/*----コンパイル・実行結果-----
C:\My Documents\Java\java_Exa\sample>javac test39.java
test39.java:8: インタフェースはコンストラクタを持つことはできません。
        test39(){
        ^
エラー 1 個
*/
//-------------test39終わり----------------//


[ 戻る ]