ホームページ >Java >&#&チュートリアル >Java ジェネリック入門の分析

Java ジェネリック入門の分析

WBOY
WBOY転載
2023-04-29 21:19:121521ブラウズ

1. ジェネリックとは何ですか?

ジェネリックとは、実際には、型をパラメーターとして渡すことを意味します。ジェネリックにより、プログラマは、後でコードを書くときに指定されたいくつかの型を使用できます。クラスをインスタンス化するときに、必要な型が渡されます。これらのタイプを指定するための引数として。

なぜジェネリックを導入するのでしょうか?

例: シーケンス テーブルを自分で実装する

public class MyArrayList {
    public int[] elem;
    public int usedSize;

    public MyArrayList() {
        this.elem = new int[10];
    }
    // add方法
    public void add(int val) {
        // 暂时不考虑扩容问题,这里只是为了讲泛型
        elem[usedSize++] = val;
    }
    // get方法
    public int get(int pos) {
        return elem[pos];
    }
}

ここで、上記のカスタマイズされたシーケンス テーブルを使用する場合、int 型の要素のみを追加できることがわかります。コレクション シーケンス テーブルにはあらゆる種類のデータを追加できますが、これはどのように実現されるのでしょうか?ここでは、どの型でも確実に渡すことができるように、最初に int 型を Object 型に変更しようとします。

public class MyArrayList {
    public Object[] elem;
    public int usedSize;

    public MyArrayList() {
        this.elem = new Object[10];
    }
    // add方法
    public void add(Object val) {
        // 暂时不考虑扩容问题,这里只是为了讲泛型
        elem[usedSize++] = val;
    }
    // get方法
    public Object get(int pos) {
        return elem[pos];
    }
}

main メソッドでオブジェクトにデータを追加するときは、任意のタイプのデータを追加できます。しかし、データを取り出す必要がある場合、返される型がObjectであるため、対応する型で受け取るために強制変換が必要となり、非常に面倒である。

public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(1);
        myArrayList.add("hello");
        int array1 = (int)myArrayList.get(0);
        String array2 = (String)myArrayList.get(1);
    }

そこで質問は、受信する前に毎回強制的に転送する必要があるのか​​ということですが、それは回避できるのでしょうか?このとき、インスタンスオブジェクトを作成する際に、必要な型をパラメータとして渡すことで、渡された型のデータをすべてこのオブジェクトに格納しておけば、取り出したときに明確に識別できるのではないかと考えました。オブジェクト内のすべてのデータ。これらはすべてこのタイプであるため、強制的に転送する必要はありません。今回はジェネリック医薬品についてご紹介します。

public class MyArrayList<E> {
	// 在编写程序时,不指定具体的类型,而用<E>这里的E来暂时代替
    // 具体的类型在实例化对象时传入
    public E[] elem;
    public int usedSize;

    public MyArrayList() {
    	// 这里的写法不是特别准确,应该用反射机制,这里先这样写
        this.elem = (E[])new Object[10];
    }
    // add方法
    public void add(E val) {
        // 暂时不考虑扩容问题,这里只是为了讲泛型
        elem[usedSize++] = val;
    }
    // get方法
    public E get(int pos) {
        return elem[pos];
    }
}
public static void main(String[] args) {

        MyArrayList<Integer> myArrayList1 = new MyArrayList<>();
        myArrayList1.add(1);
        myArrayList1.add(3);
        // myArrayList1.add("world");// 这里会报错,因为传入的数据不是指定的类型,所以泛型还有自动对类型进行检查的作用
        int I1 = myArrayList1.get(0);
        
        MyArrayList<String> myArrayList2 = new MyArrayList<>();
        myArrayList2.add("hello");
        myArrayList2.add("world");
        String s1 = myArrayList2.get(0);
    }

これにより、あらゆる種類のデータを確実に渡すことができ、取り出すときに無理に渡す必要がなくなります。ジェネリックスの意味:

1. 型を自動的にチェックする

2. 強制的な型変換を自動的に実行する

それでは、ここで MyArrayList の対応するオブジェクトの型は何でしょうか? MyArrayList などですか?

Java ジェネリック入門の分析

ここで、インスタンスによって作成されたオブジェクトの型はすべて MyArrayList であり、 の内容はジェネリック型の構成に参加していないことがわかります。 中の型はどこですか?これには、ジェネリックの動作メカニズムを理解する必要があります。

2. ジェネリックのコンパイル方法

配列とジェネリックの重要な違いは、型チェックを強制する方法です。具体的には、配列は実行時に型情報を保存および確認します。ただし、ジェネリックはコンパイル時に型エラーをチェックしますが、実行時には型情報がありません。

一般的なコンパイル メカニズム: 消去メカニズム

コンパイル中に、MyArrayList の E が Object 型に消去されます。

Java ジェネリック入門の分析

は、main メソッドですべて MyArrayList 型に変更されます。

Java ジェネリック入門の分析

以上がJava ジェネリック入門の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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