1. Pengenalan
Dalam tutorial ringkas ini, kita akan melihat jenis mentah, apakah itu, dan mengapa kita harus menjauhinya.
2. Jenis Mentah
Jenis mentah adalah nama untuk antara muka atau kelas generik tanpa argumen jenisnya:
List list = new ArrayList(); // raw type
Daripada:
List listIntgrs = new ArrayList(); // parameterized type
List adalah jenis senarai antara muka parameter manakala List adalah jenis senarai antara muka mentah .
Jenis mentah boleh berguna semasa berinteraksi dengan kod warisan bukan generik.
Jika tidak, tidak digalakkan. Ini adalah kerana:
- Mereka tidak ekspresif
- Mereka kekurangan keselamatan jenis, dan
- Masalah diperhatikan pada masa berjalan dan bukan pada waktu penyusunan
3. Tidak ekspresif
Jenis mentah tidak mendokumentasikan dan menjelaskan sendiri cara jenis parameter.
Kita dapat dengan mudah menyimpulkan bahawa Senarai jenis parameter adalah senarai yang mengandungi String s. Walau bagaimanapun, jenis mentah tidak mempunyai kejelasan ini, sehingga sukar untuk bekerja dengannya dan dengan kaedah APInya.
Mari kita lihat tandatangan kaedah get (int index) di antara muka List untuk memahami perkara ini dengan lebih baik:
/** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException if the index is out of range * (index = size()) */ E get(int index);
Kaedah get (indeks int) mengembalikan rentetan pada kedudukan indeks dalam jenis parameterized Senarai .
Namun, untuk Senarai jenis mentah , ia mengembalikan Objek . Oleh itu, kita diminta untuk melakukan usaha ekstra untuk memeriksa dan mengenal pasti jenis elemen dalam Senarai jenis mentah dan menambahkan corak jenis yang sesuai. Ini dapat memperkenalkan bug pada masa berjalan kerana jenis mentah tidak selamat digunakan .
4. Tidak Selamat Jenis
Kami mendapat tingkah laku pra-generik dengan jenis mentah. Oleh itu, Senarai jenis mentah menerima Objek dan dapat menahan unsur dari sebarang jenis data . Ini boleh menyebabkan masalah keselamatan jenis ketika kita mencampurkan jenis parameter dan mentah.
Mari kita lihat ini dengan membuat beberapa kod yang memberi contoh pada Senarai sebelum meneruskannya ke kaedah yang menerima Senarai jenis mentah dan menambahkan Integer padanya:
public void methodA() { List parameterizedList = new ArrayList(); parameterizedList.add("Hello Folks"); methodB(parameterizedList); } public void methodB(List rawList) { // raw type! rawList.add(1); }
Kod ini mendapat menyusun (dengan amaran), dan Integer akan ditambah kepada jenis mentah Senarai apabila dilaksanakan. The Senarai yang telah diluluskan sebagai argumen kini mengandungi String dan Integer .
Penyusun mencetak amaran kerana penggunaan jenis mentah:
Note: RawTypeDemo.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
5. Masalah di Runtime
Kekurangan keselamatan jenis pada jenis mentah mempunyai kesan kausal yang boleh menyebabkan pengecualian pada waktu proses.
Mari ubah contoh sebelumnya supaya kaedahA mendapat elemen pada kedudukan indeks 1 dari Senarai kami setelah memanggil kaedahB :
public void methodA() { List parameterizedList = new ArrayList(); parameterizedList.add("Hello Folks"); methodB(parameterizedList); String s = parameterizedList.get(1); } public void methodB(List rawList) { rawList.add(1); }
Kod disusun (dengan amaran yang sama) dan membuang ClassCastException ketika dijalankan. Ini berlaku kerana kaedah get (int index) mengembalikan Integer , yang tidak dapat diberikan kepada pemboleh ubah jenis String :
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
6. Kesimpulannya
Jenis mentah sukar untuk digunakan dan boleh memperkenalkan pepijat dalam kod kami.
Menggunakannya boleh mengakibatkan akibat yang boleh mendatangkan malapetaka, dan malangnya, kebanyakan bencana ini berlaku pada waktu berjalan.
Lihat semua coretan dalam tutorial ini di GitHub.