Class.forNameとClassLoader.loadClassの比較

1271 ワード


Classのマウントは、The Java Language Specificationの12.2,12.3,12.4にそれぞれ定義されるloading,linking,initializingの3段階に分かれています.
Class.forName(className)は実際にClassを呼び出します.forName(className, true, this.getClass().getClassLoader()).2番目のパラメータは、Classがloadingされた後に初期化されなければならないかどうかを意味します.
ClassLoader.loadClass(className)が実際に呼び出したのはClassLoaderです.loadClass(name,false)、2番目のパラメータはClassがlinkされているかどうかを示します.
違いが出てきました.Class.forName(className)がマウントしたclassは初期化され、ClassLoader.loadClass(className)にマウントされたclassはまだlinkされていません.
一般的に、この2つの方法の効果は同じで、Classをロードすることができます.しかし、プログラムがClassによって初期化するかどうかに依存する場合は、Classを使用する必要がある.forName(name)です.
例えば、JDBCプログラミングでは、Classという使い方がよく見られる.forName(「com.mysql.jdbc.Driver」)をgetClass().getClassLoader().loadClass(「com.mysql.jdbc.Driver」)では、できません.
どうしてですか.comを開きます.mysql.jdbc.Driverのソースコードを見てみると、
//
// Register ourselves with the DriverManager
//
static {
    try {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
        throw new RuntimeException("Can't register driver!");
    }
}

元々、Driverはstaticブロックに自分をjavaに登録していた.sql.DriverManager.staticブロックはClassの初期化で実行されます.だからここはClassしか使えない.forName(className).