26-カスタムシステムクラスローダ基礎となるソースコードの解析方法及び解析にforName

カスタムコード分析システムクラスローダとその下にある分析方法にforName

java.lang.Class
public static Class<?> forName(@NonNls String name,
                            boolean initialize,
                            ClassLoader loader)
                    throws ClassNotFoundException

指定されたクラスローダを使用して、指定された文字列名を持つクラスまたはインタフェースに関連付けられたClassオブジェクトを返します。クラスまたはインタフェースの完全修飾名を指定して、この方法の試みは、負荷を見つけ、クラスまたはインタフェースをリンクする(同じフォーマットでは、getNameが返されます)。指定されたクラスローダは、クラスまたはインタフェースをロードするために使用されます。パラメータローダがnullの場合、クラスはブートストラップクラスローダによってロードされます。クラスは、初期化パラメータがtrueの場合にのみ初期化され、それが以前に初期化されていない場合。

指定されたクラスローダを使用して返し、指定された名前または文字列に関連付けられたクラスへのインタフェースを持つクラスオブジェクトを。所与のクラスまたはインタフェースの完全修飾名(同じフォーマットを使用してのgetName戻り)は、方法の試みが見つけ、ロードおよびクラスまたはインタフェースをリンクします。ローディングクラスまたはインタフェースのために指定されたクラスローダ。出発して、クラスをロードする負荷パラメータが空の場合、(ルート)クラスローダ。初期化パラメータがtrueで、以前に初期化されていない場合にのみ、クラスが初期化されます。

名前がプリミティブ型またはvoidを表す場合、試みは無名パッケージ内でnameという名前のユーザー定義クラスを探すために行われます。したがって、この方法は、クラスのいずれかがプリミティブ型またはvoidを表すオブジェクト得るために使用することができません。

名前がプリミティブ型またはvoidを表す場合は、ユーザー定義クラスを見つけるために、名前のないパッケージの名前を命名しようとします。したがって、この方法は、元のオブジェクトがボイドの任意のタイプまたはクラスを表し得るために使用することができません。

名前が配列クラスを表す場合、配列クラスのコンポーネント型がロードされますが初期化されません。
例えば、インスタンスメソッドで式:
Class.forNameの(「fooが」)
に相当する:(上面的表达式、等价于下面的)
にClass.forName(「foo」という、真、this.getClass()のgetClassLoader())
このメソッドは、セクション12.2で指定されるように結合または初期化、ローディングに関連するエラーをスローすることを注意、12.3そしてJava言語仕様の12.4。このメソッドは、要求されたクラスがその呼び出し元にアクセス可能であるかどうかをチェックしないことに注意してください。

セクション12.2、12.3及び12.4 Java言語仕様に記載されているように、この方法は、ローディング、またはリンク初期化エラーに関連付けられたスローことに留意されたいです。このメソッドは、要求されたクラスは、発信者がアクセスすることができるかどうかを確認しないことに注意してください。

ローダがnullで、セキュリティマネージャが存在し、呼び出し側のクラスローダがnullでない場合、このメソッドは、それがブートストラップクラスにアクセスするためによいかどうかを確認するためのRuntimePermission(「のgetClassLoader」)の許可を得てセキュリティマネージャのcheckPermissionメソッドを呼び出しますローダ。

ローダが空で、セキュリティマネージャが存在し、かつクラスローダのパーティーが空でない呼び出す場合は、このメソッドを使用すると、ブートクラスローダーにアクセスできることを保証するために、セキュリティマネージャのcheckPermissionメソッドを呼び出すためのRuntimePermission(「getClassLoader」)アクセス権を使用していますデバイス。

パラメータ:
name -要求クラスの完全修飾名
初期化-真のクラスが初期化される場合。Java言語仕様のセクション12.4を参照してください。
-ローダークラスがロードされている必要があり、そこからクラスローダ
戻り値:
目的のクラス//表示所需类的类を表すクラスオブジェクト对象

Class.forNameの方法:

public static Class<?> forName(String name, boolean initialize,
                               ClassLoader loader)
   throws ClassNotFoundException
    {
        Class<?> caller = null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            // Reflective call to get caller class is only needed if a security manager
            // is present.  Avoid the overhead of making this call otherwise.
            caller = Reflection.getCallerClass(); //获取调用forName方法的那个Class对象。
            if (sun.misc.VM.isSystemDomainLoader(loader)) { 
            	//ccl:获取调用forName方法的那个Class对象的类加载器
            	ClassLoader ccl = ClassLoader.getClassLoader(caller);
                if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
                    sm.checkPermission( //进行一个安全性检查
                        SecurityConstants.GET_CLASSLOADER_PERMISSION);
                }
            }
        }
        return forName0(name, initialize, loader, caller);//这个方法是一个native方法,查看不了源码!
}
公開された25元の記事 ウォンの賞賛0 ビュー1447

おすすめ

転載: blog.csdn.net/qq_40574305/article/details/104793558