1. Kabeh kelas warisanObject

Kabeh kelas ing Jawa kanthi implisit marisi Objectkelas kasebut.

Kita bakal njelasno apa warisan lan cara kerjane ing Jawa ing Java Core nggoleki. Saiki, kita bakal nimbang siji kasunyatan prasaja saka iki:

Objek saka kelas apa wae bisa ditugasake menyang Objectvariabel. Tuladha:

Kode Cathetan
Object o = new Scanner(System.in);
Variabel onyimpen referensi kanggo Scannerobyek
Object o = new String();
Variabel onyimpen referensi kanggo Stringobyek
Object o = new Integer(15);
Variabel onyimpen referensi kanggo Integerobyek
Object o = "Hello";
Variabel onyimpen referensi kanggo Stringobyek

Iki ngendi kabar apik rampung. Compiler ora nglacak jinis asli saka obyek disimpen ing Objectvariabel, supaya sampeyan ora bakal bisa nelpon cara ing obyek disimpen liyane saka cara saka Objectkelas.

Yen sampeyan kudu nelpon metode sing digandhengake karo jinis asli obyek, mula sampeyan kudu nyimpen referensi kasebut ing variabel saka jinis sing bener, banjur nelpon metode ing variabel kasebut:

Kode Cathetan
Object o = new Scanner(System.in);
int x = o.nextInt();
Program ora bakal kompilasi. Kelas Objectora duwe nextInt()metode.
Object o = new Scanner(System.in);

Scanner console = (Scanner) o;

int x = console.nextInt();
Iki bakal bisa.

Ing kene kita nyimpen referensi kanggo Scannerobyek ing Scannervariabel nggunakake operator typecast .

Sampeyan ora bisa mung pindhah lan nemtokake Objectvariabel menyang variabel Scanner, sanajan Objectvariabel nyimpen referensi Scannerobyek. Nanging sampeyan bisa nindakake iki yen sampeyan nggunakake operator typecast , sing wis sampeyan ngerti. Iki minangka tampilan umume:

Type name1 = (Type) name2;

Where name1jeneng variabel Type, lan name2jeneng Objectvariabel sing nyimpen referensi kanggo Typeobyek.

Typecasting

Yen jinis variabel lan jinis obyek ora cocog, banjur a ClassCastExceptionbakal dibuwang. Tuladha:

Kode Cathetan
Object o = new Integer(5);
String s = (String) o;
Kesalahan bakal kedadeyan nalika runtime:
a ClassCastExceptionbakal dibuwang ing kene

Ana cara kanggo ngindhari kesalahan iki ing Jawa: kita nindakake iki kanthi mriksa jinis obyek sing disimpen ing variabel :

name instanceof Type

Operator instanceofmriksa manawa namevariabel kasebut minangka Typeobyek.

Minangka conto, ayo goleki senar ing macem-macem obyek:

Kode Cathetan
Object[] objects = {10, "Hello", 3.14};

for (int i = 0; i < objects.length; i++)
{
   if (objects[i] instanceof String)
   {
      String s = (String) objects[i];
      System.out.println(s);
   }
}
Autoboxing bakal ngowahi nilai kasebut dadi Integer, String, lan Double, mungguh.

Loop liwat Uploaded obyek

Yen obyek iku String

Simpen menyang Stringvariabel
Tampilake variabel ing layar.


2. Napa generik muncul - koleksi

Ayo bali menyang koleksi.

Sanalika pangembang Jawa nggawe ArrayListkelas kasebut, dheweke pengin nggawe universal, supaya bisa nyimpen samubarang jinis obyek. Supaya padha nggunakake Uploaded Objects kanggo nyimpen unsur.

Kekuwatan pendekatan iki yaiku sampeyan bisa nambah obyek saka jinis apa wae ing koleksi kasebut.

Mesthi, ana sawetara kelemahane.

Kekurangan 1.

Iku tansah perlu kanggo nulis operator konversi jinis nalika njupuk unsur saka koleksi:

Kode Cathetan
ArrayList numbers = new ArrayList();


for (int i = 0; i < 10; i++)
   numbers.add(i * 10);


int sum = 0;
for (int i = 0; i < 10; i++)
{
   sum = sum + (Integer) numbers.get(i);
}
Nggawe koleksi kanggo nyimpen referensi kanggo Objectobyek

Isi koleksi karo nomer 10, 20, ... 100;



Jumlah unsur koleksi


Typecasting perlu

Kekurangan 2.

Ora ana jaminan manawa koleksi ngemot jinis unsur tartamtu

Kode Cathetan
ArrayList numbers = new ArrayList();


for (int i = 0; i < 10; i++)
   numbers.add(i * 2.5);


int sum = 0;
for (int i = 0; i < 10; i++)
{
   sum = sum + (Integer) numbers.get(i);
}
Nggawe koleksi kanggo nyimpen referensi kanggo Objectobyek

Kita ngisi koleksi kanthi nomer sing diwakili minangka Doubleobyek:
0.0, 2.5, 5.0, ...


Jumlah unsur koleksi


Bakal ana kesalahan: a Doubleora bisa dikirim menyangInteger

Data bisa dilebokake ing koleksi ing ngendi wae:

  • ing cara liyane
  • ing program liyane
  • saka file
  • liwat jaringan

Kekurangan 3.

Data ing koleksi bisa diganti kanthi ora sengaja.

Sampeyan bisa ngirim koleksi sing diisi data menyang sawetara cara. Cara kasebut, sing ditulis dening programmer sing beda, nambahake data menyang koleksi sampeyan.

Jeneng koleksi ora jelas nuduhake jinis data sing bisa disimpen ing njero. Lan sanajan sampeyan menehi variabel jeneng sing jelas, referensi kasebut bisa diterusake menyang puluhan metode, lan metode kasebut mesthi ora ngerti apa-apa babagan jeneng asli variabel kasebut.


3. Generik

Generik ing Jawa

Ing Jawa, kabeh masalah iki diilangi dening bab keren iki disebut generik.

Ing Jawa, generik tegese kemampuan kanggo nambah parameter jinis menyang jinis. Asil minangka jinis komposit kompleks. Pandangan umum saka jinis komposit kasebut yaiku:

ClassName<TypeParameter>

Iki minangka kelas umum. Lan bisa digunakake ing ngendi wae sampeyan biasane nggunakake kelas.

Kode Katrangan
ArrayList<Integer> list;
Nggawe variabel
list = new ArrayList<Integer> ();
Nggawe obyek
ArrayList<Integer>[] array;
Nggawe larik

Mung Integervariabel sing bisa disimpen ing koleksi kasebut:

Kode Katrangan
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(new Integer(1));
list.add(2);
list.add("Hello");
ArrayListkoleksi karo Integerunsur
Iki diijini
Lan iki uga bakal bisa
Autoboxing

Nanging iki ora diidini: kesalahan kompilasi

Sampeyan bakal sinau carane nggawe kelas dhewe karo paramèter jinis ing nggoleki Java Collections. Saiki, kita bakal nliti cara nggunakake lan cara kerjane.


4. Cara kerja generik

Bener, generik banget primitif.

Compiler mung ngganti jinis umum karo jinis biasa. Nanging nalika cara saka jinis umum digunakake, compiler nambah operator typecast kanggo cast paramèter kanggo paramèter jinis:

Kode Apa compiler ora
ArrayList<Integer> list = new ArrayList<Integer>();
ArrayList list = new ArrayList();
list.add(1);
list.add( (Integer) 1 );
int x = list.get(0);
int x = (Integer) list.get(0);
list.set(0, 10);
list.set(0, (Integer) 10);

Contone, kita duwe metode sing nyimpulake nomer ing koleksi integer:

Kode Apa compiler ora
public int sum(ArrayList<Integer> numbers)
{
   int result = 0;

   for (int i = 0; i < numbers.size(); i++)
      result = result + numbers.get(i);

   return result;
}
public int sum(ArrayList numbers)
{
   int result = 0;

   for (int i = 0; i < numbers.size(); i++)
      result = result + (Integer) numbers.get(i);

   return result;
}

Ing tembung liya, generik minangka jinis gula sintaksis, kaya autoboxing, nanging luwih sithik. Kanthi autoboxing, compiler nambahake cara kanggo ngowahi lan intlan Integerkosok balene, lan kanggo generik nambah operator typecast.

Sawise kompiler nyusun kelas umum sampeyan kanthi paramèter jinis, mung diowahi dadi kelas biasa lan operator typecast. Informasi babagan argumen jinis sing diterusake menyang variabel jinis umum wis ilang. Efek iki uga diarani tipe erasure .

Kadhangkala programer nulis kelas umum (kelas kanthi paramèter jinis) mbutuhake informasi babagan jinis sing diterusake minangka argumen. Ing nggoleki Java Collections, sampeyan bakal sinau babagan carane ngatasi iki lan apa sing ana.



5. Sawetara kanyatan babagan generik

Kene sawetara fakta sing luwih menarik babagan generik.

Kelas bisa duwe sawetara jinis paramèter. Iku katon kaya iki:

ClassName<TypeParameter1, TypeParameter2, TypeParameter3>

Bener, iki ora nggumunake. Nang endi wae compiler bisa nambah operator kanggo cast kanggo siji jinis, bisa nambah sawetara operator typecast.

Tuladha:

Kode Cathetan
HashMap<Integer, String> map = new HashMap<Integer, String>();
map.put(7, "Hello");
map.put(-15, "Hello");
Parameter pisanan metode putyaiku Integer, lan nomer loro yaiku aString

Jinis umum uga bisa digunakake minangka paramèter . Iku katon kaya iki:

ClassName<TypeParameter<TypeParameterParameter>>

Upaminipun kita pengin nggawe dhaptar sing bakal nyimpen dhaptar strings. Ing kasus iki, kita bakal entuk kaya iki:

// 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);

Jinis umum (jinis kanthi paramèter jinis) uga bisa digunakake minangka jinis array. Iku katon kaya iki:

ClassName<TypeParameter>[] array = new ClassName<TypeParameter>[size];

Ora ana kedadeyan gaib ing kene: kurung sudut mung nuduhake jeneng jinis:

Kode Mitra non-generik
ArrayList<String>[] list = new ArrayList<String>[10];
StringArrayList[] list = new StringArrayList[10];
ArrayList<Integer>[] list = new ArrayList<Integer>[10];
IntegerArrayList[] list = new IntegerArrayList[10];
ArrayList<Scanner>[] list = new ArrayList<Scanner>[10];
ScannerArrayList[] list = new ScannerArrayList[10];