2016-12-13 7 views
9

によって配列を置き換えることができます。問題は、コンソールに[[Ljava.lang.Objectと表示されることを期待していたことです。クラスローダは、私は次のJavaコードを実行すると何も

効果で、JVM specificationに、私は次のように読むことができます:

配列クラスは、Java仮想マシン(§5.3.3)で直接作成された

、ないクラスローダによって。しかしながら、Dの定義クラスローダーはObject[][]ので配列クラスC.

を作成するプロセスで使用される配列のクラスであり、私は私のfindClass引数[[Ljava.lang.Objectとその要素で呼び出されないと仮定しタイプjava.lang.Objectと入力します。再帰アルゴリズムが実際に記載されている「配列クラスの作成」セクションでさらに

は、:

コンポーネントタイプが参照型である場合、この節(§5.3)のアルゴリズムを用いて再帰的に適用されますクラスローダLロードし、それによってC.

のコンポーネントタイプを作成するために、だから私の質問は以下のとおりです。

  • 私はこのOUTPを取得していますなぜut? JVMが私のためにやっているのではなく、ClassLoaderの内部にこの再帰アルゴリズムを手動で組み込む必要があるのでしょうか?これが意味するところなら、それを行う最善の方法は何ですか?
  • 最初の引用で「作成済み」を誤解していますか?ランタイム配列クラスを作成できないということだけを意味しますが、まだロードを修正できますか?
+1

OPのポイントは、スペックは配列クラスの場合、JVMがクラスローダーの使用を避けてクラスを直接ロードすることを示しているようです。そして、これはとても良い質問です。 –

+0

はい、私は目的のために、配列の要素型の読み込みをパッチするだけでした(テストするだけです)。しかし代わりに、配列全体が置き換えられています。 – Codoscope

答えて

4

あなたはJVMの仕様について質問していますが、テストではという独立したクラスのjava.lang.ClassLoaderの動作を示しています。 JVMが配列クラスをロードしている場合、JVMはクラスローダーを完全にバイパスします。これは、JVMは、カスタムクラスローダを持つクラスをロードしようとさせることで証明することができる。

Class<?> clazz = Class.forName("[[Lcom.foo.Test;", true, new ClassLoader() { 
    @Override 
    public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { 
     System.out.println("Loading " + name); 
     return super.loadClass(name, resolve); 
    } 
}); 
System.out.println(clazz); 

出力:あなたが見ることができるように

 
Loading com.foo.Test 
class [[Lcom.foo.Test; 

、コンポーネントタイプは、最初のクラスローダによってロードされます配列型は暗黙的にロードされます。

関連する問題