ホームページ  >  記事  >  Java  >  Java 型消去は本当にすべての情報を完全に消去できるのでしょうか?

Java 型消去は本当にすべての情報を完全に消去できるのでしょうか?

angryTom
angryTom転載
2019-11-28 16:20:172070ブラウズ

Java 型消去は本当にすべての情報を完全に消去できるのでしょうか?

背景: ジェネリクスは基本的に型の「型パラメータ」を提供することは誰もが知っています。これらは、パラメータ化された型 (パラメータ化された型) またはパラメトリック多態性 (パラメトリック多態性) とも呼ばれます。実際、ジェネリックの考え方は Java で初めて導入されたものではなく、C のテンプレートがジェネリックの使用例です。

(推奨ビデオ: Java ビデオ チュートリアル)

GJ (Generic Java) はJava 言語の拡張機能であり、パラメータ化された型を備えた Java 言語です。 GJ で書かれたプログラムは、パラメータ化された型が多く、型変換が少ない点を除けば、基本的には通常の Java プログラムと同じように見えます。実際、これらの GJ プログラムは、ジェネリックを持たない通常の Java プログラムに変換されてから処理され、コンパイラによってジェネリック Java から通常の Java への変換が自動的に完了します。

类型擦除真的能完全擦除一切信息吗?java 泛型揭秘

実際の Java ジェネリックとは何ですか

コンパイラーがジェネリック消去を実行することは誰もが知っています。プログラム (ジェネリックスを含む Java コード) では、ジェネリック型情報を使用して型安全性を確保し、ジェネリックスなしでは検証できない多数の型安全性制約を検証し、同時に生成されたバイトコード内でこれらの型情報をクリアします。 まず確認してみましょう:

public static void main(String[] args) {
 ArrayList<Integer> ints = new ArrayList<Integer>();
 ints.add(1); 
 ints.add(2);
 ints.add(3);
 ArrayList<String> sts = new ArrayList<String>();
 sts.add("a");
 sts.add("b");
 sts.add("c");
 System.out.println(ints.getClass() == sts.getClass()); 
}

上に出力された結果は true です。なぜなら、

理解によれば、一般的な消去の後は元の値を取得できないということです。タイプは次のとおりです。すべてオブジェクトの形式です。本当にそうなのでしょうか?

次のコードを見てください:

import java.lang.reflect.ParameterizedType;import java.util.ArrayList;import java.util.List;public class ClassTest {     
public static void main(String[] args) throws Exception {
     ParameterizedType type = (ParameterizedType) 
     Bar.class.getGenericSuperclass();
     System.out.println(type.getActualTypeArguments()[0]);
     
     ParameterizedType fieldType = (ParameterizedType) 
     Foo.class.getField("children").getGenericType();
     System.out.println(fieldType.getActualTypeArguments()[0]);
     
     ParameterizedType paramType = (ParameterizedType) 
     Foo.class.getMethod("foo", List.class)
     .getGenericParameterTypes()[0];
     System.out.println(paramType.getActualTypeArguments()[0]);
     
     System.out.println(Foo.class.getTypeParameters()[0]
     .getBounds()[0]);
     }     
     class Foo<E extends CharSequence> {     
     public List<Bar> children = new ArrayList<Bar>();     
     public List<StringBuilder> foo(List<String> foo) {return null; }     
     public void bar(List<? extends String> param) {}
     }     
     class Bar extends Foo<String> {}
    }

印刷出力

class java.lang.Stringclass com.javapuzzle.davidwang456.ClassTest$Barclass java.lang.Stringinterface java.lang.CharSequence

各型パラメータが保持され、実行時にリフレクション メカニズムを通じて取得できることがわかります。では、「型消去」とは一体何なのでしょうか?少なくとも何かは消去されましたよね?はい。実際には、構造化情報以外はすべて消去されます。ここで構造化情報とは、プログラムの実行フローではなく、クラスの構造に関連する情報を指します。つまり、クラス、そのフィールド、およびそのメソッドの型パラメータに関連するメタデータは保存され、リフレクションを通じて取得できます。

この記事は、php 中国語 Web サイトの java チュートリアル 列からのものです。学習へようこそ!

以上がJava 型消去は本当にすべての情報を完全に消去できるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。