Java の一般的なメカニズムについて話しましょう

王林
リリース: 2021-01-27 09:59:06
転載
2229 人が閲覧しました

Java の一般的なメカニズムについて話しましょう

インタビュアー: Java の一般的なメカニズムについて教えてください。

(学習ビデオ共有: Java ビデオ チュートリアル)

ライト バージョンの回答

Java を開発する場合、ダイヤモンド構文 < > を使用して、Makeクラス、インターフェイス、またはメソッドには、ジェネリック参照をパラメータとして受け入れるクラスのグループがあります。ジェネリック クラスは、最終的には山括弧内の規則によって定義されます。ジェネリック クラスは通常、大文字 (通常は文字 T) で表され、後で Java コンパイラによって渡されます。コンパイル中に、ジェネリックスは消去され、使用される特定のクラスに従って置き換えられ、クラスのバイトコードが生成されるため、ジェネリックスは Jvm に対して透過的です。

デラックス版の回答

ジェネリックは JDK1.5 で正式に導入されました

Java でのジェネリックの導入の背景

Java コレクションでは、複数の型をput in , たとえば

    List list=new ArrayList();
    list.add("String");
    list.add(1024);
ログイン後にコピー

これは JDK1.5 以前の一般的な使用方法でした。現在の JDK の下に配置しても許可されています。その場合、このコレクションの使用はいくつかの問題を引き起こす可能性があります。コレクションにどの型が配置されているかを知っているのは、コレクションを作成した人だけです。他の呼び出し元はそれをまったく判断できません。大規模なプロジェクトでは、問題が発生する可能性が非常に高くなります。呼び出し元がコレクション内のオブジェクトを強制的に転送すると、型が間違っていると、エラーが報告されます。この種のエラーは、その時点のコンパイル段階では見つけることができず、実行時にのみ見つかります。同様の問題を解決するために、JDK ではジェネリックスが導入されました。

ジェネリック型

ジェネリックスの導入後は、コンパイル段階で型が要件を満たしているかどうかをチェックできるため、ブラインド型変換が大幅に排除されます。 ジェネリックは主にコンパイラで動作するため、コンパイル後の JVM は実行中にジェネリックを認識できません。 ジェネリックは、通常のジェネリックとワイルドカード ジェネリックに分類されます。

1. 通常のジェネリックス

名前が示すように、このタイプのジェネリックスは呼び出し時に任意の型の受け渡しをサポートしますが、呼び出し時には等号の左側と右側のジェネリックスが必要です。一貫性を保つこと。 JDK1.7の右側の菱形は省略可能です。

class Test<T>{...} //声明时
Test<Integer> test = new Test<Integer>(); //调用时
Test<Integer> test = new Test(); //1.7调用时
ログイン後にコピー

3. 境界付きジェネリック

<?>//无界泛型,任意类型都匹配
<T extends ClassA>//有界泛型 - 继承自某父类
<T extends InterfaceB>//有界泛型 - 实现某接口
<T extends ClassA & InterfaceB & InterfaceC ... >//有界泛型 - 多重边界
<T super ClassC>//有界泛型 - 指定类父类
ログイン後にコピー

ジェネリック消去

先ほど述べたように、ジェネリックはコードの作成時とコンパイル時にのみ機能し、Jvmはクラスをロードします ランタイムは目に見えず透過的ですコンパイラはコンパイル時にジェネリックスを消去するため、簡単かつ大まかに言うと、クラスまたはメソッドの <> 山括弧を削除し、山括弧内の規則に従うことを意味します。特定のクラスに変更すると、Jvmランタイムは、このコードに以前にジェネリックが存在したことを認識しません。これは互換性のために行われます。前述したように、ジェネリックは JDK1.5 でのみ導入されました。このようにして、ジェネリックが導入されたとしても、現在、一部の JVM ではメジャーが必要ありませんコンパイラはコンパイラを変更するだけで済みます。コンパイラは認識できるが、仮想マシンは認識できないこの種の構文を、人々はこの構文をシュガー (シュガー) と呼びます。コンパイラ デシュガー処理の後、ドライな情報が取得され、コンパイラーに渡されます。実行用の仮想マシン。

(推奨グラフィック チュートリアル: java 入門チュートリアル)

ジェネリック消去メカニズム

//Pair的泛型
public class Pair<T> {

    private T mFirst;
    private T mSecond;

    public T getmFirst() {
        return mFirst;
    }

    public void setmFirst(T mFirst) {
        this.mFirst = mFirst;
    }

    public T getmSecond() {
        return mSecond;
    }

    public void setmSecond(T mSecond) {
        this.mSecond = mSecond;
    }
}

//Pair的原始类型
//无论何时定义一个泛型类型,都会自动提供一个相应的 原始类型
public class Pair {

    private Object mFirst;
    private Object mSecond;

    public Object getFirst() {
        return mFirst;
    }

    public void setFirst(Object mFirst) {
        this.mFirst = mFirst;
    }

    public Object getSecond() {
        return mSecond;
    }

    public void setmSecond(Object mSecond) {
        this.mSecond = mSecond;
    }
}

//如果调用Pair<T extends String>编译擦除后得到如下=
class Pair{
    private String mFirst;
    private String mSecond;
    ...
}
ログイン後にコピー

ジェネリックがメソッドの入力パラメータとして使用される場合、消去後、追加メソッドなどのワイルドカード ジェネリックの下限に置き換えられます

public static void insertElements(List<? super A> list){
    //Add进来的都是层级“小于等于”A的,也就是下界
    list.add(new A());
    list.add(new B());
    list.add(new C());
}
ログイン後にコピー

ジェネリックがメソッドの戻りパラメーターとして使用される場合、後続のワイルドカード ジェネリックの上限に置き換えられます。 get メソッドなどの消去

public void processElements(List<? extends A> elements){
   //for循环挨个get list 里的数据,都当做A,也就是都当做上界
   for(A a : elements){
      System.out.println(a.getValue());
   }
}
ログイン後にコピー

ジェネリック型消去についてどれだけ話しても、どれだけ多くのブログを読んでも、公式の定義は公式の定義ほど正確ではありません。型消去に関する Oracle の公式ドキュメント

Type Erasure
Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.Insert type casts if necessary to preserve type safety.Generate bridge methods to preserve polymorphism in extended generic types.Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
ログイン後にコピー

面接の質問の詳細については、次をクリックしてください: Java 面接の質問と回答

以上がJava の一般的なメカニズムについて話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.im
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート