[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 1446] Re: import 宣言はど っちのスタイルがよいか



澤田です。

On Mon, 27 Nov 2000 16:35:50 +0900 (JST)
in [jfriends-ml 1445] Re: import 宣言はどっちのスタイルがよいか
Shin <shin@xxxxxxxxx> wrote:

> >> 私JDBC使ったことがないんですが、これなんでA.classとかじゃ駄目なん
> >> でしたっけ?(と安易に聞いてしまう^^)
> >> # A.classじゃ最適化で消される危険があるから?またはその他の要因でク
> >> # ラスのロードがされないことがある?
> >
> >最適化で消されちゃうという危険性もあるかもしれませんが、
> >それよりも、そもそもロードするドライバをどれにするかをパラメータに
> >したいという要求があると思います。
> 
> もしそうだとしたら、いったいどれくらいの人がJDBCドライバクラスを
> パラメタ化しているんでしょうね。

現在私が絡んでいるプロジェクトではというと、「JDBCドライバをロード
してコネクションを得る」ところまでをファクトリとして作っちゃって、
それを切り替えるようにしてます。ですからパラメタ化と言っても
直接 Class.forName である理由にはなってないですね。


> 結構環境構築込みの案件なら決め打ちになりそうだし、何よりその必要性が
> 無い限りは静的に検査できるものを、わざわざ実行時検査しか出来ない方を
> 進めている理由が分からなかったりします。

そうですね。木下さんのおっしゃる通り、「最適化によって消えてしまう」
ことだけが本当の理由なのかもしれません。


***

ところで、
「そういえば A.class; ってどういうコードになるんだろう?」
という疑問がふと湧いたので試してみました。

ソース:

class T {
  public static Class foo() {
    Class c = T.class;
    return c;
  }

  public static Class bar() throws Exception {
    Class c = Class.forName("X");
    return c;
  }
}


クラスファイルを javap -c したもの:

Compiled from T.java
class T extends java.lang.Object {
    static java.lang.Class class$T;
    T();
    public static java.lang.Class foo();
    public static java.lang.Class bar() throws java.lang.Exception;
    static java.lang.Class class$(java.lang.String);
}

Method T()
   0 aload_0
   1 invokespecial #6 <Method java.lang.Object()>
   4 return

Method java.lang.Class foo()
   0 getstatic #7 <Field java.lang.Class class$T>
   3 ifnonnull 18
   6 ldc #8 <String "T">
   8 invokestatic #9 <Method java.lang.Class class$(java.lang.String)>
  11 dup
  12 putstatic #7 <Field java.lang.Class class$T>
  15 goto 21
  18 getstatic #7 <Field java.lang.Class class$T>
  21 astore_0
  22 aload_0
  23 areturn

Method java.lang.Class bar()
   0 ldc #10 <String "X">
   2 invokestatic #1 <Method java.lang.Class forName(java.lang.String)>
   5 astore_0
   6 aload_0
   7 areturn

Method java.lang.Class class$(java.lang.String)
   0 aload_0
   1 invokestatic #1 <Method java.lang.Class forName(java.lang.String)>
   4 areturn
   5 astore_1
   6 new #3 <Class java.lang.NoClassDefFoundError>
   9 dup
  10 aload_1
  11 invokevirtual #4 <Method java.lang.String getMessage()>
  14 invokespecial #5 <Method java.lang.NoClassDefFoundError(java.lang.String)>
  17 athrow
Exception table:
   from   to  target type
     0     5     5   <Class java.lang.ClassNotFoundException>


私の解釈が間違っていなければ、

・A.class という表記は結局は Class.forName() の呼び出しになる。
・ただし、ClassNotFoundException を catch した場合は
  代わりに NoClassDefFoundError を throw する。

となりますね。考えてみれば A.class; と書いて例外を意識した事はないし、
NoClassDefFoundError になるのも当然なのですが、JDBC ドライバの場合は
「実行環境にはインストールされていない」状況もありえます。
そういうミスに対処させようとすると、ClassNotFoundException のままの
方が実装者には親切かもしれない・・と考えました。

こじつけでしょうか(^^;?

___
澤田 大輔(die)
email: die@xxxxxxxx(home), swd@xxxxxxxxxxxxxxxx(office)
「積読」 http://www.techbrains.co.jp/~swd/book/