1. ホーム
  2. java

[解決済み] Class.forName()」と「Class.forName().newInstance()」の違いは何ですか?

2022-04-23 12:22:40

質問

とはどのような違いがあるのでしょうか? Class.forName()Class.forName().newInstance() ?

私は重要な違いを理解していない(私はそれらについて何かを読んだことがある!)。あなたは私を助けることができるでしょうか?

どのように解決するのですか?

この2つのメソッドがどのように使われるかを示す例が、理解を深めるのに役立つかもしれません。そこで、次のようなクラスを考えてみましょう。

package test;

public class Demo {

    public Demo() {
        System.out.println("Hi!");
    }

    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("test.Demo");
        Demo demo = (Demo) clazz.newInstance();
    }
}

javadocで説明されているように、このメソッドは Class.forName(String) が返されます。 Class 与えられた文字列の名前を持つクラスまたはインターフェイスに関連付けられたオブジェクト。 を返す。 test.Demo.class に影響される。 clazz 型の変数 Class .

次に clazz.newInstance() で表されるクラスの新しいインスタンスを作成します。 Class オブジェクトを作成します。このクラスは、あたかも new 式で、引数リストが空であること。 つまり、これはここでは実際に new Demo() の新しいインスタンスを返します。 Demo .

そして、これを実行すると Demo クラスは、このように次のような出力をします。

Hi!

従来の new というのは newInstance を使えば、実行するまでわからないクラスをインスタンス化することができ、コードがよりダイナミックになります。

典型的な例はJDBC APIで、仕事を実行するために必要な正確なドライバを実行時にロードします。EJBsコンテナやServletコンテナは、実行前に何も知らないコンポーネントをロードして作成するために、動的な実行時ロードを使用します。

さらに詳しく知りたい方は、Ted Newardの論文を見てください。 Class.forName()を理解する をパラフレーズしたものです。

EDIT (コメントとして投稿されたOPからの質問に答えて)。JDBCドライバの場合は、少し特殊です。の中で説明されているように ドライバマネージャ の章を参照してください。 JDBC API入門 :

(...) A Driver クラスがロードされ したがって、自動的に と共に DriverManager は、次の2つのうちどちらかです。 の方法があります。

  1. メソッドを呼び出すことで Class.forName . これは明示的にロードします。 ドライバクラスを作成します。このクラスは 外部設定に依存しないので、この方法 ドライバをロードする方法として推奨されるのは を使用するためのものです。 DriverManager フレームワークを使用します。次のコードでは クラス acme.db.Driver :

     Class.forName("acme.db.Driver");
    
    

もし acme.db.Driver を読み込むと インスタンスが生成され、さらに DriverManager.registerDriver その インスタンスをパラメータとする (それが のはずです)であれば、それは DriverManager のドライバ一覧と 接続を作成するために利用可能です。

  1. (...)

これらのいずれの場合も、新しく読み込まれた Driver を呼び出して自分自身を登録する必要があります。 DriverManager.registerDriver . 前述のように、これはクラスがロードされたときに自動的に行われるはずです。

初期化中に自分自身を登録するために、JDBCドライバは通常、このような静的な初期化ブロックを使用します。

package acme.db;

public class Driver {

    static {
        java.sql.DriverManager.registerDriver(new Driver());
    }
    
    ...
}

呼び出し Class.forName("acme.db.Driver") の初期化を行います。 acme.db.Driver クラスを作成し、静的初期化ブロックを実行します。また Class.forName("acme.db.Driver") は確かにインスタンスを作成しますが、これは(良い)JDBCドライバがどのように実装されているかの結果に過ぎません。

余談ですが、JDBC 4.0(Java7からデフォルトのパッケージとして追加)とJDBC 4.0ドライバの新しいオートローディング機能により、これらすべてが不要になったことをお伝えしておきます。以下を参照してください。 Java SE 6におけるJDBC 4.0の強化点 .