De ce următoarele tipuri sunt reifiable și non-reifiable în java? (Programare, Java, Generice, Ștergere De Tip)

Prateek a intrebat.

În informatică, reificarea a ajuns să însemne o reprezentare explicită a unui tip – adică informații de tip în timp de execuție.

Tutoriale oracle spune ,

Un tip reificabil este un tip ale cărui informații de tip sunt complet disponibile în timpul execuției. Aceasta include primitive, tipuri non-generice, tipuri brute și invocări de wildcards nelegate.

Tipurile nereifiabile sunt tipuri ale căror informații au fost eliminate în momentul compilării prin ștergerea tipului – invocări de tipuri generice care nu sunt definite ca wildcards fără limită.

Un tip este reficabil dacă este unul dintre următoarele:

  1. un tip primitiv (cum ar fi int) //înțeles
  2. un tip de clasă sau de interfață neparametrizat (cum ar fi Number, , String, , sau Runnable) // de ce
  3. Un tip parametrizat în care toate argumentele de tip sunt wildcards nelimitate (cum ar fi List<?>, , ArrayList<?>, , sau Map<?, ?>) // de ce
  4. Un tip brut (cum ar fi List, , ArrayList, , sau Map) // de ce
  5. Un array al cărui tip de componentă este reficabil (cum ar fi int[], , Number[], , List<?>[], , List[], , sau int[][]) // de ce

Un tip nu este reificabil dacă este unul dintre următoarele:

  1. o variabilă de tip (cum ar fi T) // de ce
  2. un tip parametrizat cu parametri reali (cum ar fi List<Number>, , ArrayList<String>, , sau Map<String, Integer>) // de ce
  3. Un tip parametrizat cu o limită (cum ar fi List<? extends Number> sau Comparable<? super String>) // de ce

De ce 2,3,4,5 este reificabil și 6,7,8 este nereficabil?

Comentarii

  • Un tip reificabil este un tip ale cărui informații de tip sunt complet disponibile în momentul execuției. Aceasta include primitive, tipuri non-generice, tipuri brute și invocări de wildcards nelegate. –  > Por Suresh Atta.
  • @Prateek Eu aș începe mai întâi cu întrebarea „Cum folosesc Google pentru a găsi informații?”. –  > Por occulus.
  • Această întrebare pare a fi în afara subiectului, deoarece se referă la definirea unei caracteristici lingvistice care este ușor de găsit folosind Google. –  > Por occulus.
  • @occulus mi-am schimbat întrebarea.Vă rog să vă uitați la ea. –  > Por Prateek.
  • Această întrebare ESTE / TREBUIE să fie în domeniul de aplicare Stackoverflow. Este vorba despre utilizarea caracteristicilor limbajului în Java și despre cum să le folosiți (înțelegând de ce este definit în acest fel). Este în regulă să nu știi ceva și să lași pe altcineva să răspundă. Dar nu o aruncați la designul limbajului, haideți băieți! –  > Por Salvador Valencia.
7 răspunsuri
LBC

Sun/Oracle spune motivul este o combinație de:

  • Nevoie: verificarea tipului în timp de compilare este suficientă
  • Dimensiunea codului: evitarea umflării codului de tip STL
  • Performanță: evitarea verificării tipurilor în timpul execuției, care a fost deja efectuată la compilare.

Ștergerea tipurilor asigură că nu sunt create clase noi pentru tipurile parametrizate; în consecință, genericele nu implică costuri suplimentare la execuție.

Pe scurt, 1-5 pot fi refăcute pentru că pur și simplu rămân aceleași tipuri ca cele specificate în cod, astfel încât nu există informații de tip pierdute/șterse, dar 6-8 vor pierde informații de tip în timpul compilării (chestiile dintre <>), astfel încât nu pot fi accesate în timpul execuției.

Comentarii

  • Cred că acest răspuns este cel care răspunde la întrebare în modul cel mai direct! –  > Por GhostCat.
  • ce este STL. ce reprezintă? –  > Por samshers.
  • @samshers STL face referire la biblioteca standard de șabloane C++ care a implementat tipuri „generice” folosind o abordare care generează cod pentru fiecare tip specific pe baza unei abordări de șablon, de unde și numele. –  > Por LBC.
CrazyCoder

Înțelegeți semnificația acestor doi termeni.

Reifiable înseamnă al cărui tip este complet disponibil în momentul execuției, ceea ce înseamnă că compilatorul java nu are nevoie de niciun proces de ștergere a tipului.

Nerevizuibil înseamnă că compilatorul java are nevoie de un proces de ștergere a tipului deoarece tipul nu este complet disponibil.

Un tip este reifiabil dacă este unul dintre următoarele:

1. Un tip primitiv (cum ar fi int) :

Aici gândiți-vă că atunci când scrieți sau utilizați orice int ca referință, credeți că compilatorul are nevoie de un proces de identificare a tipului int? nu, deoarece int este int…. același pentru toate tipurile primitive.

2. O clasă sau un tip de interfață neparametrizată (cum ar fi Number, String sau Runnable).

Același răspuns ca și în răspunsul anterior, conform căruia compilatorul nu are nevoie de nici o ștergere de tip pentru Number, String sau Runnable.

3. Un tip parametrizat în care toate argumentele de tip sunt wildcards nelimitate (cum ar fi List<?>, ArrayList<?>, sau Map<?, ?>).

Toate caracterele wildcard nelimitate sunt acceptate ca tip reifiabil, deoarece sunt deja menționate în definiția tipului reifiabil; acum depinde de dezvoltatorul API de ce le consideră ca fiind un tip reifiabil.

4. Un tip brut (cum ar fi List, ArrayList sau Map) ::

același răspuns ca la prima întrebare

5. Un array al cărui tip component este reifiable (cum ar fi int[], Number[], List<?>[], List[] sau int[][]) ::

același răspuns ca la prima întrebare

Un tip nu este reiabil dacă este unul dintre următoarele:

6. O variabilă de tip (cum ar fi T) :

Deoarece java nu poate identifica tipul lui T, compilatorul are nevoie de ștergerea tipului pentru a identifica tipul.

7. Un tip parametrizat cu parametri reali (cum ar fi List<Number>, ArrayList<String>, sau Map<String, Integer>).:

Aici, toate tipurile sunt de tip generic, iar în momentul execuției compilatorul vede lista ca listă … deci, conform definiției de nereifiabilitate, toate aceste colecții sunt considerate ca fiind nereifiabile.

8. Un tip parametrizat cu o limită (cum ar fi List<? extends Number> sau Comparable<? super String>).

Același răspuns ca și cel anterior

Comentarii

  • -1 De ce vreți să spuneți că sub compiler needs type erasure to identify the type? Este foarte confuz și cel mai probabil pur și simplu greșit. Din câte știu eu, motivul principal pentru ștergerea tipurilor în Java a fost nevoia de compatibilitate cu codul scris înainte de adăugarea funcției Generics. –  > Por Alex Yursha.
Nicio idee pentru nume

ați putea pune aceeași întrebare lui Google:

tip reifiable

Atunci când folosiți generice, de cele mai multe ori, informațiile de tip la compilare se pierd. În timpul execuției, adesea tot ceea ce știe programul despre o referință este că este o referință la un fel de Obiect. În cazul în care toate informațiile despre tip sunt cunoscute și în timpul execuției, tipul se numește „reifiable”. Poate că, într-o bună zi, genericele vor fi reproiectate astfel încât toate tipurile să poată fi redefinite.

Comentarii

  • Mi-am schimbat întrebarea, iar soluția nu este disponibilă pe Google –  > Por Prateek.
  • Există un motiv pentru care tipurile reificabile sunt ușor diferite față de alte limbaje. Java a fost mai mult preocupat să nu întrerupă compatibilitatea bytecode. Este dezamăgitor Stackoverflow evită o întrebare bună prin aruncarea FAQ în fața ta. –  > Por Salvador Valencia.
Sajal Dutta

Un tip reificabil este un tip ale cărui informații de tip sunt complet disponibile la momentul execuției. Aceasta include primitive, tipuri non-generice, tipuri brute și invocări de wildcards nelegate.

Tipurile nereifiabile sunt tipuri ale căror informații au fost eliminate în momentul compilării prin ștergerea tipului – invocări de tipuri generice care nu sunt definite ca wildcards fără limită. Un tip nereifiabil nu are toate informațiile sale disponibile în momentul execuției. Exemple de tipuri nereifiabile sunt List<String> și List<Number>; JVM nu poate face diferența între aceste tipuri în timpul execuției. După cum se arată în Restricții privind genericele, există anumite situații în care tipurile nereifiabile nu pot fi utilizate: de exemplu, într-o expresie instanceof sau ca element într-o matrice.

Referință

linkerro

Java a implementat inițial reflecția în versiunea 1.1.

Clasele generice au fost introduse în versiunea 5.0.

Atunci când s-au introdus clasele generice s-a decis ca, din motive de compatibilitate retroactivă, informațiile despre tipurile generice să fie șterse la execuție. Acest lucru a permis codului scris înainte de generice să funcționeze cu codul bazat pe generice fără modificări.

De exemplu, un List[Integer32] ar fi fost tradus de compilator în Integer32[]Toate verificările de tip vor fi efectuate la compilare, iar dacă ceva nu este luat în considerare, va fi generată o eroare la execuție.

Acest detaliu de implementare a însemnat că genericele nu au fost reificate (nu există o implementare specifică a acestora în VM) și, prin urmare, ori de câte ori se încearcă să se reflecte tipul generic, informațiile returnate vor fi cele ale tipului de bază. Un alt motiv pentru care acest lucru ar fi avantajos este că nu ar trebui să fie emisă de către VM nicio implementare pentru tipurile reificate ori de câte ori este utilizat unul dintre acestea (în c#, de exemplu, ori de câte ori se utilizează un tip generic, implementarea reală a acestuia este generată de către VM în timpul execuției, împreună cu metadatele de reflectare, ceea ce înseamnă că performanța este afectată ori de câte ori trebuie generat un nou tip).

Comentarii

  • Interesant, acum înțeleg motivul pentru care cu Java 8 nu au fost introduse noi bytecodes. Codul lambda trebuie compilat în bytecode-ul original din versiunile Java anterioare. –  > Por Salvador Valencia.
DMGinMD

Este doar o presupunere, dar bănuiesc că cheia pentru a înțelege acest lucru este să recunoaștem că, deși Java este un limbaj puternic tipizat și verifică referințele de tip ca parte a procesului de compilare, în multe cazuri informațiile de tip nu sunt de fapt necesare pentru a executa logica. În acest caz, codul byte generat poate ști că lucrează cu o instanță a unui obiect, dar nu cunoaște tipul. Acest lucru ar avea sens mai ales în condițiile în care limbajele care nu utilizează tipărirea puternică pot fi generate ca bytecode java. Astfel, dacă tipul obiectului a fost eliminat, instanța nu ar putea fi refăcută.

LrsNate

Nu sunt pe deplin sigur că am înțeles întrebarea dumneavoastră, dar s-ar putea să vă referiți la tipurile de obiecte, spre deosebire de tipurile primitive. Această întrebare este cu atât mai importantă cu cât tipurile primitive, cum ar fi int sau double, nu pot fi utilizate ca tipuri generice – de aici și clasele lor de înfășurare, cum ar fi Integer.

// This won't work
ArrayList<int> list = new ArrayList<int>();
// But this will
ArrayList<Integer> list = new ArrayList<Integer>();

Pentru a rezuma, aș spune că toate obiectele – și doar obiecte – sunt refolosibile. (și, prin urmare, pot fi utilizate ca instanțiere de tipuri generice)

Comentarii

  • un tip primitiv este, de asemenea, reifiabil.Vă rugăm să consultați tutorialele Oracle pentru a fi mai clar –  > Por Prateek.