2

Javaクラスローダーがどのように機能するか、具体的にはメソッドを理解しようとしていますdefineClass(String,byte[],int,int)。のクラス定義をロードしたいとしますNonIntrinsicTypeNonIntrinsicTypeの*.classファイルを見つけて、その内容をbyte[]呼び出されたにシリアル化してbytesから、を呼び出すことができることを知っていますdefineClass(null,bytes,0,bytes.length)

私が理解するのに苦労している奇妙な状況は、byte[]次のようなクラス定義のを取得するには[LNonIntrinsicTypeどうすればよいですか?つまり、アプリケーションがのインスタンスのクラス定義を要求した場合NonIntrinsicType[]、*。classファイルがありませんこれは、このクラスタイプに対応します。byte[]このタイプの定義のを取得するにはどうすればよいですか?

なぜ私がこれをやりたいのか疑問に思われるかもしれません。私は基本的に、クラスパスにクラス定義がある「ローカル」JVMと、クラスパスに前述のクラス定義がない「リモート」JVMを使用して、ネットワーククラスローダーを作成しようとしています。「リモート」はのインスタンスに遭遇し、NonIntrinsicType[]そのクラスタイプの「ローカル」からの定義を要求しますが、私の「ローカル」JVMはのクラスファイルを見つけることができないため、「リモート」にNonIntrinsicType[]クラス定義を提供できません。byte[]

2010年9月7日追加

私が言及すべき1つのこと...私は「ローカル」によって「リモート」に送信されたメッセージを使用Socketして受信しています。「リモート」側でObjectInputStreamのカスタム拡張を作成し、オーバーライドしました。これは、着信メッセージにまだロードされていないクラスのインスタンスが含まれている場合に、「リモート」JVMが受け取る最初の通知です。クラス定義を渡すために使用する別のソケットがあるため、最初のソケットがロードされていないクラスのインスタンスを受信すると、2番目のソケットを介して「ローカル」JVMからそのクラスの定義を要求します。ObjectInputStreamprotected Class<?> resolveClass(ObjectStreamClass)

この問題は、配列型のクラス名を返すカスタムObjectInputStream.resolveClass(ObjectStreamClass)が渡されたときに発生します(名前は次のようになります)。基本レベルの型を簡単に解析して最初にロードできます。これは、の呼び出しで実行されます。ここで、基本レベルのクラスのを取得し、それを使用してそのメソッド呼び出し内で呼び出します。ObjectStreamClass[Lsome.ClassName;some.ClassNameNetworkClassLoader.getInstance.loadClass()byte[]defineClass()

配列型のクラス定義のを取得できない可能性があることを理解したので、配列型のインスタンスbyte[]を見つけて返す方法を理解しようとしています。「リモート」JVMのメッセージ受信に関するカスタムClass<?>のメソッドのコードは次のとおりです。resolveClassObjectInputStreamSocket

@Override
protected Class<?> resolveClass(ObjectStreamClass osc) 
        throws IOException, ClassNotFoundException{
    try {
        return super.resolveClass(osc);
    } catch (Exception e){}

    String name = osc.getName();
    boolean array = name.contains("[L");

    if(array) name = name.replace("[L","").
            replace("[","").replace(";","");

    Class<?> c = NetworkClassLoader.getInstance().loadClass(name);
    if(!array) return c;

    //If it's an array type, how do I obtain its corresponding
    //Class<?> and return it here?

    throw new ClassNotFoundException();
}
4

5 に答える 5

4

の定義を作成する必要はありません[LType。がある場合は、リフレクションを使用してそのクラスの配列Classを作成できます。

Object array = Array.newInstance(yourClass, dimensions);
于 2012-09-06T23:25:12.787 に答える
2

配列はロードされないため、配列のロードを制御することはできません。ロードするものは何もありません。配列のクラスはありません。クラス定義はありません。バイト[]はありません。

于 2012-09-06T23:17:16.857 に答える
0

配列クラスは、を呼び出さずにJVMによって作成されdefineClass()ます。

http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.3.3を参照してください

于 2012-09-07T02:50:17.457 に答える
0

これを行う唯一の方法は、JVM の defineClass(...) メソッドにパッチを適用して必要なクラスを探し、後で使用できるように保存することです。

于 2012-09-06T23:37:43.337 に答える
0

ClassLoader javadocからの抜粋:

配列クラスのクラス オブジェクトは、クラス ローダーでは作成されませんが、Java ランタイムの必要に応じて自動的に作成されます。Class.getClassLoader() によって返される配列クラスのクラス ローダーは、その要素型のクラス ローダーと同じです。要素型がプリミティブ型の場合、配列クラスにはクラス ローダーがありません。

クラスローダーが のクラスを作成するように求められる方法を理解することは興味深いでしょう[LNonIntrinsicType。カスタムをしている感じです。何をしているかを詳しく説明していただければ、問題をよりよく理解できます。クラスローダーが定義するように求められたときのコールスタックは何[LNonIntrinsicTypeですか?

于 2012-09-07T02:55:03.800 に答える