Ovladajte Java instanceof ključnu reč
„Sanmej, danas ćemo proći jedno vrlo jednostavno znanje, instanceof ključnu reč.“
„Ne treba ti, brate, da objašnjavaš, danas ću promeniti formu, ja ću tebi objasniti.“ Sanmej je ponosno rekla.
instanceof ključna reč je zapravo vrlo jednostavna za korišćenje:
(object) instanceof (type)Namena je takođe vrlo jednostavna, procenjuje da li objekat odgovara navedenom tipu, rezultat je ili true, ili false. Pri deserijalizaciji, instanceof operator je vrlo koristan, jer u to vreme nismo sigurni da li objekat pripada navedenom tipu, ako ne procenimo, lako se baca ClassCastException izuzetak.
Napravimo ovako jednostavnu klasu Round:
class Round {
}Zatim dodajemo proširenu klasu Ring:
class Ring extends Round {
}U ovom trenutku, možemo koristiti instanceof da proverimo da li Ring objekat pripada Round tipu.
Ring ring = new Ring();
System.out.println(ring instanceof Round);Rezultat će ispisati true, jer Ring nasleđuje Round, što znači da Ring i Round zadovoljavaju is-a odnos, a instanceof operator je upravo baziran na nasleđivanju između klasa i realizaciji između klase i interfejsa.
Još jednom napravimo interfejs Shape:
interface Shape {
}Zatim napravimo Circle klasu koja implementira Shape interfejs i nasleđuje Round klasu:
class Circle extends Round implements Shape {
}Ako je objekat napravljen od ove klase, rezultat instanceof će sigurno biti true.
Circle circle = new Circle();
System.out.println(circle instanceof Circle);Ovo sigurno nema problema, instanceof upravo to radi, svi lako razumaju. Ako je tip roditeljska klasa?
System.out.println(circle instanceof Round);Rezultat će sigurno biti i dalje true, jer i dalje zadovoljava is-a odnos. Ako je tip interfejs?
System.out.println(circle instanceof Shape);Rezultat je i dalje true, jer takođe zadovoljava is-a odnos. Ako između objekta i tipa koji se porede nema odnos, naravno ne možete koristiti instanceof za poređenje.
Da bismo potvrdili ovo, napravimo Triangle klasu koja implementira Shape ali nema veze s Circle:
class Triangle implements Shape {
}U ovom trenutku, ako ponovo koristimo instanceof za poređenje, kompajler će prijaviti grešku.
System.out.println(circle instanceof Triangle);Greška je prikazana ispod:
Inconvertible types; cannot cast 'com.itwanger.twentyfour.instanceof1.Circle' to 'com.itwanger.twentyfour.instanceof1.Triangle'Znači tipovi se ne podudaraju, ne mogu se konvertovati, cilj našeg korišćenja instanceof je nadati se da ako je rezultat true, može se izvršiti konverzija tipa. Ali očito Circle ne može postati Triangle.
Kompajler nam je unapred pomogao da predvidim, vrlo pametan.
Java je objektno-orijentisani programski jezik, što znači da osim osnovnih tipova podataka, sve klase implicitno nasleđuju Object klasu. Zato sledeći rezultat će sigurno ispisati true.
Thread thread = new Thread();
System.out.println(thread instanceof Object);„Ako je objekat null?“ U ovom trenutku sam se uključio.
„Ovo je stvarno dobro pitanje.“ Sanmej mi je dala veliki palac.
System.out.println(null instanceof Object);Samo objekti mogu imati null vrednost, zato kompajler neće prijaviti grešku, samo za null, instanceof rezultat je false. Jer svi objekti mogu biti null, zato nije lako odrediti kojoj klasp pripada null.
Obično, ovako koristimo instanceof operator.
// prvo procenimo tip
if (obj instanceof String) {
// zatim prisilno konvertujemo
String s = (String) obj;
// zatim možemo koristiti
}Prvo koristimo instanceof za procenu tipa, zatim prisilno konvertujemo obj u očekivani tip i koristimo.
Kada je JDK 16, instanceof podudaranje uzorka je postalo službeno, znači da je korišćenje instanceof pogodnije.
if (obj instanceof String s) {
// ako se tip podudara, direktno koristimo s
}Možete direktno dodati promenljivu pri if proceni tipa, ne treba prisilnu konverziju i deklaraciju nove promenljive.
„Vau, ovako je jednostavnije!“ Da bih podržao Sanmej, ne samo sam se čudio!
„Dobro, o instanceof operatoru ćemo za sada ovako, nije teško, nadam se da ćeš i ti dobro ovladati.“ Sanmej se smešila, izgleda da uživa u procesu podučavanja.
