Este - arhivă

Identificați tipul în timpul rulării

Luați în considerare mecanismul de identificare a tipului în timp de execuție (RTTI - identificarea timpului de execuție).

Acest mecanism este alcătuit din mai multe părți, care se disting prin importanța, complexitatea și frecvența utilizării.







  • Instrumentele de bază RTTI stau la baza mecanismului de polimorfism. În consecință, ele sunt utilizate în mod constant atunci când se programează în Java.
  • Când accesați pentru prima dată o anumită clasă din program, creați un obiect Clasă pentru acea clasă. Acest lucru se aplică și în cazul instalațiilor RTTI.
  • Mecanismele de determinare a tipurilor (claselor) de obiecte în timpul rulării sunt utilizate destul de des. Cel mai simplu dintre aceste mecanisme este exemplul de funcționare. am luat deja în considerare.
  • Cel mai complex mecanism al RTTI este reflecția. Acesta este un set de instrumente care vă permit să obțineți informații complete despre o clasă, cum ar fi o listă de câmpuri, constructori, metode etc. Informațiile obținute pot fi folosite pentru a crea obiecte din această clasă, apelați la metodele sale.

Facilități de bază RTTI

Orice turnare de tipuri de la bază la copil (conversie de tip downcast, downcasting) se realizează cu controlul dinamic al corectitudinii tipului.

Deci, să spunem că avem clasa Base:

Clasele Derived1 sunt generate din aceasta. Derived2 Derived3. În program, construim obiectele din aceste clase și le punem în lista ArrayList. Apoi vrem să trecem prin aceste obiecte și să sunăm f () pentru fiecare dintre ele. Va arăta așa.

Undeva în program am descris ArrayList.

La un alt punct al programului

Aici, următoarea metodă a interfeței Iterator returnează Object. Dar știm că există obiecte de clasă Derived1 din listă. Derived2 și Derived3. clasa de bază pentru care este baza. Nu putem apela f () pentru Object. Așa că o aducem la Base și sună f ().

Acesta este un exemplu de aplicare a polimorfismului. Dar cel mai important lucru care nu poate fi uitat este că în acest caz, ca și în alte cazuri similare, în timpul executării programului se va efectua un control dinamic de tip. Dacă există un obiect al unei alte clase în lista pentru care baza nu este clasa de bază, va apărea un ClassCastException în timpul executării.

În plus, comenzile de tip dinamic în această situație vor apela metoda dorită f (). Nu am spus nimic despre cursurile Derived1. Derived2 și Derived3. Dar în oricare dintre ele putem suprascrie metoda f (). În același timp, în acest fragment pentru fiecare obiect din listă, va fi apelată metoda f () din clasa sa. Și nu trebuie să luăm măsuri speciale pentru acest lucru.

Obiecte de clasă

Obiectele de clasă sunt create pentru fiecare clasă utilizată în program când este accesată pentru prima dată. Primul acces la o clasă poate fi crearea unei instanțe de clasă sau a unui apel către o metodă sau câmp static. Există și alte opțiuni în cadrul mecanismului RTTI.

Având acces la un obiect Clasă. corespunzând unei anumite clase, puteți crea o instanță a acestei clase, puteți obține numele clasei și puteți extrage multe informații diferite despre clasă.

Să ne întoarcem la documentație. Pachet clasa de clasa java.lang.

Primul lucru de reținut este lipsa constructorilor publici și descrierea clasei în sine:

Aceasta înseamnă că nu putem moșteni această clasă și nici nu creăm în mod explicit obiecte din această clasă. Clasa de clasă este proiectată astfel încât să nu puteți crea mai mult de un obiect pentru fiecare clasă. Mașina virtuală Java (VM) creează automat un astfel de obiect la prima accesare a clasei.

Există mai multe moduri de a obține acest obiect pentru o anumită clasă.

  • Utilizând o metodă statică de clasă de clasă
  • Folosind o construcție sintactică numită literali de obiecte de clasă.
  • Folosind metoda getClass a clasei Object.






În primul caz, trebuie să cunoaștem numele complet al clasei. În al doilea rând, clasa trebuie să fie disponibilă în fișierul java dat (utilizând instrucțiunea de import). Ultima opțiune poate fi folosită pentru a obține un obiect Class dintr-un obiect dintr-o anumită clasă.

Puteți utiliza oricare dintre aceste metode, în funcție de ceea ce ne este disponibil la un moment dat în program. Dar, dacă alte lucruri sunt egale, este mai bine să dai preferință celei de-a doua dintre aceste metode - folosirea literalurilor obiectului de clasă.

Litere de obiecte de clasă

Sintaxa acestei construcții este foarte simplă:

va da o referință la obiectul Class pentru clasa java.util.ArrayList.

Această opțiune este preferabilă celorlalte deoarece este controlată la momentul compilării. În plus, este mai ușor decât alte opțiuni.

Obiectele de clasă sunt create nu numai pentru toate clasele implicate în program, dar și pentru tipurile primitive. În plus, literalul obiectelor de clasă reprezintă una dintre cele două modalități de a accesa aceste obiecte. Principalul lucru este să știi cum să-l scrii în program.

De exemplu, pentru int, literalul corespunzător arată astfel: int.class.

Alternativ, puteți folosi câmpul TYPE static într-o clasă de înfășurare pentru acest tip simplu. De exemplu, pentru int. Integer.TYPE.

Determinarea tipului de obiect din program

Uneori în program este necesar să se determine sau să se verifice tipul obiectului. Cel mai adesea, o astfel de nevoie apare atunci când se realizează o downcasting de clase (downcasting) pentru a verifica fezabilitatea unei astfel de transformări.

Una dintre metodele pe care le-am luat deja în considerare la cea de-a opta sesiune. Acesta este un exemplu de operațiune.

O altă metodă este o consecință a materialului discutat mai sus în clasa de clasă.

A treia cale este de a folosi metoda isInstance a clasei.

Luați în considerare și comparați aceste metode.

La cea de-a 8-a sesiune am considerat acest exemplu

Așa cum puteți vedea din exemplu, operandul stâng al exemplului operației este un obiect, dreptul este clasa.

O altă modalitate de a compara este compararea obiectelor de clasă. Deoarece pentru fiecare clasă un astfel de obiect este prezent în singular, atunci, după obținerea a două referințe la un obiect de clasă de clasă. ele pot fi comparate pur și simplu cu egalitatea. În exemplul de mai sus, aceasta ar putea arăta astfel:

Cu toate acestea, această metodă de comparare diferă de comparație utilizând exemplul. În mod special, în acest exemplu este valabil numai dacă clasa Carte nu are moștenitori. Dacă vă imaginați că clasa Carte are moștenitori (de exemplu, Fantasy și DetectiveStory), atunci pentru obiectele din aceste clase, verificați

În același timp, verificați

(adică, utilizând exemplul operației) va funcționa corect, deoarece această operație funcționează cu moștenirea claselor.

Aceasta este diferența dintre metodele de comparație descrise mai sus, care trebuie luate în considerare. Cel mai adesea avem nevoie de ceea ce face. și numai în cazuri rare, putem fi interesați de o comparație exactă a claselor care pot fi realizate prin compararea referințelor la obiectele de clasă.

În cele din urmă, există o opțiune de comparare utilizând metoda isInstance din clasa de clasă. În semantica sa, această metodă nu este diferită de aplicarea instanței de operare. Diferențele lor sunt pur sintactice. Deci, pentru exemplul nostru, aplicația esteInstance ar arăta astfel

Crearea obiectelor folosind metoda newInstance

Să revenim la documentația pentru clasă. Printre metodele acestei clase este metoda newInstance.

Această metodă permite obiectului clasei pentru care a fost creat acest obiect Clasă. Adevărul este că se utilizează constructorul implicit (utilizați ceilalți constructori de mai jos).

Pentru a vă familiariza cu această metodă, luați în considerare un exemplu.

Este un program interactiv cu câmp de text pentru a introduce numele clasei și zona de text pentru a afișa rezultatele creării obiectelor de clasă folosind metoda newInstance.

Vom re-difuza și vom rula programul. Să facem niște teste. Mai jos, în Fig. sunt prezentate rezultatele testelor.

Ca nume de clase în acest test, au fost introduse 5 linii: abc. String. java.lang.String. java.lang.Integer și javax.swing.JLabel. Ne vom ocupa de cazurile de teste nereușite.

  • abc - nu există o astfel de clasă.
  • String - trebuie să specificați numele complet al clasei cu pachetul.
  • java.lang.Integer - nu există constructor implicit pentru această clasă.

Acest program demonstrează modul în care funcționează metodele forName și newInstance. Operațiile principale ale programului sunt concentrate în metoda createObject. Această metodă selectează mai întâi numele de clasă introdus de utilizator din câmpul de text. Apoi, în blocul de încercare. cu ajutorul metodei forName obține o referință la obiectul Class pentru această clasă și creează un obiect din această clasă folosind metoda newInstance.

Ca metodă forName. iar metoda newInstance poate face excepții. Exemplul de testare prezentat în Fig. demonstrează acest lucru. Când ați introdus numele abc și String, excepția ClassNotFoundException a apărut în metoda forName. Atunci când a fost introdus java.lang.Integer, a fost aruncată o InstantiationException în metoda newInstance.

Am analizat capabilitățile de bază ale RTTI. Rămâne pentru noi să luăm în considerare cea mai dificilă parte a reflecției RTTI.







Trimiteți-le prietenilor: