5

重複の可能性:
Java のバイトコードを表示するには?

型消去後にクラス ファイルで Java コンパイラによって行われたコード変更を確認できるかどうかを知りたいです。

javap を試してみましたが、元のソース ファイルがパラメータ化された型で再構築されます。

チュートリアル ( http://docs.oracle.com/javase/tutorial/java/generics/genTypes.html ) では、パラメーター化された型を境界型または型消去後のオブジェクトに置き換えることについて説明しています。javap や逆コンパイラでは表示されない、コンパイラによってどのような変更が行われたかを確認したいと考えています。

よろしく、サトウィク

4

2 に答える 2

1

型消去とは文字通り、結果のバイト コードからジェネリック型が削除されることを意味します。それがないことで注目に値します。そのため、バイトコードには存在しないことがわかります。

を使用するjavapと、クラス、メソッド、およびフィールドのシグネチャにいくつかのジェネリック型情報が使用できることがわかります。これが含まれているのは、コンパイラがこれらのクラスを使用してコードをコンパイルするジョブを実行できるようにするためです。これらは実行時に何もしませんが、リフレクションを介して利用できるため、この情報を使用するライブラリを作成できます。

于 2012-07-16T10:41:29.887 に答える
0

私が遭遇したケースはCollections.max()、型消去を望んでいたがObject、それでも型消去を強制する場合でしたComparable。あなたはそのように署名を見ることができます:

vlad@vld /tmp $ javap java.util.Collections | grep max
    public static java.lang.Object max(java.util.Collection);
    public static java.lang.Object max(java.util.Collection, java.util.Comparator);

javap -c別の方法は、コンパイラーによって実行されたチェックを使用して確認することです。例:

このプログラムの場合:

public class Test{
    public static void main(String[]args){
        java.util.Vector<String> a = new java.util.Vector<String>();
        a.add("Hello world");
        System.out.println(a.get(0).length());
    }
}

次の結果が得られます。

Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:    aload_0
   1:    invokespecial    #1; //Method java/lang/Object."<init>":()V
   4:    return

public static void main(java.lang.String[]);
  Code:
   0:    new    #2; //class java/util/Vector
   3:    dup
   4:    invokespecial    #3; //Method java/util/Vector."<init>":()V
   7:    astore_1
   8:    aload_1
   9:    ldc    #4; //String Hello world
   11:    invokevirtual    #5; //Method java/util/Vector.add:(Ljava/lang/Object;)Z
   14:    pop
   15:    getstatic    #6; //Field java/lang/System.out:Ljava/io/PrintStream;
   18:    aload_1
   19:    iconst_0
   20:    invokevirtual    #7; //Method java/util/Vector.get:(I)Ljava/lang/Object;
   23:    checkcast    #8; //class java/lang/String
   26:    invokevirtual    #9; //Method java/lang/String.length:()I
   29:    invokevirtual    #10; //Method java/io/PrintStream.println:(I)V
   32:    return

}

に注意してcheckcastください。

于 2012-07-16T10:49:54.083 に答える