1. Semua kelas mewarisiObject
Semua kelas di Jawa secara tersirat mewarisi Object
kelas tersebut.
Kami akan menganalisis apakah warisan dan cara ia berfungsi dalam Java dalam pencarian Java Core. Buat masa ini, kami akan mempertimbangkan satu fakta mudah yang berikut daripada ini:
Objek dari mana-mana kelas boleh diberikan kepada Object
pembolehubah. Contoh:
Kod | Catatan |
---|---|
|
Pembolehubah o menyimpan rujukan kepada Scanner objek |
|
Pembolehubah o menyimpan rujukan kepada String objek |
|
Pembolehubah o menyimpan rujukan kepada Integer objek |
|
Pembolehubah o menyimpan rujukan kepada String objek |
Di sinilah berita baik itu berakhir. Pengkompil tidak menjejaki jenis objek asal yang disimpan dalam Object
pembolehubah, jadi anda tidak akan dapat memanggil kaedah pada objek yang disimpan selain daripada kaedah kelas Object
.
Jika anda perlu memanggil kaedah yang dikaitkan dengan jenis asal objek, maka anda perlu terlebih dahulu menyimpan rujukan kepadanya dalam pembolehubah jenis yang betul, dan kemudian memanggil kaedah pada pembolehubah itu:
Kod | Catatan |
---|---|
|
Program tidak akan disusun. Kelas Object tidak mempunyai nextInt() kaedah. |
|
Ini akan berjaya. Di sini kami menyimpan rujukan kepada Scanner objek dalam Scanner pembolehubah menggunakan operator taip . |
Anda tidak boleh pergi dan menetapkan Object
pembolehubah kepada pembolehubah Pengimbas, walaupun Object
pembolehubah itu menyimpan rujukan Scanner
objek. Tetapi anda boleh melakukan ini jika anda menggunakan operator taip , yang sudah anda ketahui. Ini adalah penampilan umumnya:
Type name1 = (Type) name2;
Di manakah name1
nama pembolehubah Type
, dan name2
ialah nama Object
pembolehubah yang menyimpan rujukan kepada Type
objek.
Typecasting
Jika jenis pembolehubah dan jenis objek tidak sepadan, maka a ClassCastException
akan dilemparkan. Contoh:
Kod | Catatan |
---|---|
|
Ralat akan berlaku semasa runtime: a ClassCastException akan dilemparkan ke sini |
Terdapat cara untuk mengelakkan ralat ini dalam Java: kami melakukan ini dengan menyemak jenis objek yang disimpan dalam pembolehubah :
name instanceof Type
Operator instanceof
menyemak sama ada name
pembolehubah adalah Type
objek.
Sebagai contoh, mari kita cari rentetan dalam pelbagai objek yang pelbagai:
Kod | Catatan |
---|---|
|
Autoboxing akan menukar nilai ini kepada Integer , String , dan Double , masing-masing. Gelung ke atas tatasusunan objek Jika objek ialah String Simpan ke String pembolehubah Paparkan pembolehubah pada skrin. |
2. Mengapa generik muncul — koleksi
Mari kembali kepada koleksi.
Sebaik sahaja pembangun Java mencipta ArrayList
kelas, mereka mahu menjadikannya universal, supaya ia boleh menyimpan sebarang jenis objek. Jadi mereka menggunakan tatasusunan Object
s untuk menyimpan elemen.
Kekuatan pendekatan ini ialah anda boleh menambah objek dalam apa jua jenis pada koleksi.
Sudah tentu, terdapat beberapa kelemahan.
Kelemahan 1.
Ia sentiasa perlu untuk menulis operator penukaran jenis apabila mendapatkan semula elemen daripada koleksi:
Kod | Catatan |
---|---|
|
Cipta koleksi untuk menyimpan rujukan kepada Object objek Isi koleksi dengan nombor 10 , 20 , ... 100 ; Jumlahkan elemen koleksi Typecasting adalah perlu |
Kelemahan 2.
Tiada jaminan bahawa koleksi mengandungi jenis elemen tertentu
Kod | Catatan |
---|---|
|
Cipta koleksi untuk menyimpan rujukan kepada Object objek Kami mengisi koleksi dengan nombor yang diwakili sebagai Double objek: 0.0 , 2.5 , 5.0 , ... Jumlahkan elemen koleksi Akan terdapat ralat: a Double tidak boleh dihantar keInteger |
Data boleh dimasukkan ke dalam koleksi di mana-mana sahaja:
- dalam kaedah lain
- dalam program lain
- daripada fail
- melalui rangkaian
Kelemahan 3.
Data dalam koleksi boleh ditukar secara tidak sengaja.
Anda boleh menghantar koleksi yang diisi dengan data anda kepada beberapa kaedah. Kaedah itu, yang ditulis oleh pengaturcara yang berbeza, menambahkan datanya pada koleksi anda.
Nama koleksi tidak menunjukkan dengan jelas jenis data yang boleh disimpan di dalamnya. Dan walaupun anda memberikan nama yang jelas kepada pembolehubah anda, rujukan kepadanya boleh dihantar kepada sedozen kaedah, dan kaedah tersebut pastinya tidak akan mengetahui apa-apa tentang nama asal pembolehubah itu.
3. Generik
Di Jawa, semua masalah ini dihapuskan oleh perkara hebat ini yang dipanggil generik.
Di Java, generik bermaksud keupayaan untuk menambah parameter jenis pada jenis. Hasilnya ialah jenis komposit yang kompleks. Pandangan umum jenis komposit sedemikian adalah ini:
ClassName<TypeParameter>
Ini adalah kelas generik. Dan ia boleh digunakan di mana sahaja anda biasa menggunakan kelas.
Kod | Penerangan |
---|---|
|
Mencipta pembolehubah |
|
Mencipta objek |
|
Mencipta tatasusunan |
Hanya Integer
pembolehubah boleh disimpan dalam koleksi sedemikian:
Kod | Penerangan |
---|---|
|
ArrayList koleksi dengan Integer elemen Ini dibenarkan Dan ini juga akan berfungsi
Autoboxing
Tetapi ini tidak dibenarkan: ralat penyusunan |
Anda akan belajar cara membuat kelas anda sendiri dengan parameter jenis dalam pencarian Java Collections. Buat masa ini, kita akan melihat cara menggunakannya dan cara ia berfungsi.
4. Cara generik berfungsi
Sebenarnya, generik adalah sangat primitif.
Pengkompil hanya menggantikan jenis generik dengan jenis biasa. Tetapi apabila kaedah jenis generik digunakan, pengkompil menambah operator taip untuk menghantar parameter kepada parameter jenis:
Kod | Apa yang dilakukan oleh pengkompil |
---|---|
|
|
|
|
|
|
|
|
Katakan kita mempunyai kaedah yang menjumlahkan nombor dalam koleksi integer:
Kod | Apa yang dilakukan oleh pengkompil |
---|---|
|
|
Dalam erti kata lain, generik adalah sejenis gula sintaksis, sama seperti autoboxing, tetapi lebih sedikit. Dengan autoboxing, pengkompil menambah kaedah untuk menukar an int
kepada an Integer
dan sebaliknya, dan untuk generik ia menambah operator taip.
Selepas pengkompil menyusun kelas generik anda dengan parameter jenis, ia hanya ditukar kepada kelas biasa dan operator taip. Maklumat tentang jenis argumen yang dihantar kepada pembolehubah jenis generik hilang. Kesan ini juga dipanggil pemadaman jenis .
Kadangkala pengaturcara menulis kelas generik (kelas dengan parameter jenis) benar-benar memerlukan maklumat tentang jenis yang diluluskan sebagai hujah. Dalam pencarian Java Collections, anda akan belajar cara menangani perkara ini dan perkara yang diperlukan.
5. Sedikit fakta tentang generik
Berikut adalah beberapa fakta menarik tentang generik.
Kelas boleh mempunyai beberapa jenis parameter. Ia kelihatan seperti ini:
ClassName<TypeParameter1, TypeParameter2, TypeParameter3>
Sebenarnya, ini tidak terlalu mengejutkan. Di mana-mana pengkompil boleh menambah operator untuk menghantar kepada satu jenis, ia boleh menambah berbilang operator taip.
Contoh:
Kod | Catatan |
---|---|
|
Parameter pertama kaedah put ialah a Integer , dan yang kedua ialah aString |
Jenis generik juga boleh digunakan sebagai parameter . Ia kelihatan seperti ini:
ClassName<TypeParameter<TypeParameterParameter>>
Katakan kita ingin membuat senarai yang akan menyimpan senarai rentetan. Dalam kes ini, kita akan mendapat sesuatu seperti ini:
// List of greetings
ArrayList<String> listHello = new ArrayList<String>();
listHello.add ("Hello");
listHello.add ("Hi");
// List of goodbyes
ArrayList<String> listBye = new ArrayList<String>();
listBye.add("Bye");
listBye.add ("Goodbye");
// List of lists
ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
lists.add(listHello);
lists.add(listBye);
Jenis generik (jenis dengan parameter jenis) juga boleh digunakan sebagai jenis tatasusunan. Ia kelihatan seperti ini:
ClassName<TypeParameter>[] array = new ClassName<TypeParameter>[size];
Tiada apa-apa yang ajaib berlaku di sini: kurungan sudut hanya menunjukkan nama jenis:
Kod | Rakan sejawatan bukan generik |
---|---|
|
|
|
|
|
|
GO TO FULL VERSION