De ce autoboxing-ul Java nu se extinde la invocarea metodelor metodelor de tip autoboxed?

Vreau să convertesc un primitiv la un șir și am încercat:

myInt.toString();

Aceasta nu reușește cu eroarea:

int cannot be dereferenced

Acum, primesc că primitivele nu sunt tipuri de referință (adică nu un obiect) și astfel nu pot avea metode. Cu toate acestea, Java 5 a introdus autoboxing și unboxing (a la C# ... pe care niciodată nu mi-a plăcut-o în C#, dar asta e în afara punctului). Deci, cu autoboxing, m-aș aștepta ca cele de mai sus să-mi convertesc un intreg la un Integer și apoi să apel la toString() pe asta.

Mai mult, cred că C# permite un astfel de apel, dacă nu-mi amintesc incorect. Este doar un nefericit neajuns al specificațiilor Java autoboxing / unboxing, sau există un motiv bun pentru asta?

0
fr hi bn

8 răspunsuri

Autoboxing / unboxing Java nu merge în măsura în care vă permite să dereference un primitiv, astfel încât compilatorul dvs. îl împiedică. Compilatorul dvs. încă mai știe myInt ca primitiv. Există o lucrare despre această problemă la jcp.org .

Autoboxingul este util în principal în timpul alocării sau trecerii parametrilor - permițându-vă să transmiteți un primitiv ca obiect (sau invers) sau să atribuiți primitiv unui obiect (sau invers).

Deci, din păcate, ar trebui să o faci așa: (kudos Patrick, mi-am schimbat drumul)

Integer.toString(myInt);
0
adăugat

Ditto pe ceea ce a spus Justin, dar ar trebui să faceți asta în schimb:

Integer.toString(myInt);

Salvează o alocare sau două și este mai ușor de citit.

0
adăugat

Ar fi util ca Java să definească anumite metode statice pentru a opera pe tipuri primitive și a încorporat în compilator unele zahăr sintactic, astfel încât

5.asInteger

ar fi echivalent cu

some.magic.stuff.Integer.asInteger(5);

Nu cred că o astfel de caracteristică ar cauza incompatibilități cu orice cod care se compilează în conformitate cu regulile actuale și ar contribui la reducerea aglomerației sintactice în multe cazuri. În cazul în care Java se afla la primitivele autobox care au fost dereferențiate, oamenii ar putea presupune că ar fi cartografiat sintaxa de dereferencing la apelurile de metode statice (ceea ce este efectiv ceea ce se întâmplă în .NET) și astfel operațiunile scrise în această formă nu au fost mai costisitoare decât ar fi invocările metodelor statice echivalente. Adăugarea unei noi funcții de limbă care ar încuraja oamenii să scrie cod rău (de exemplu, primitive auto-boxing dereferențiate) nu pare a fi o idee bună, deși ar putea fi permise metodele de stil de dereferențiere.

0
adăugat

Sintaxa valabilă cea mai apropiată de exemplul dvs. este

((Integer) myInt).toString();

Când compilatorul se termină, este echivalent cu

Integer.valueOf(myInt).toString();

Cu toate acestea, aceasta nu funcționează la fel de bine ca utilizarea convențională, String.valueOf (myInt) , deoarece, cu excepția cazurilor speciale, creează o nouă instanță Integer, apoi o aruncă imediat, rezultând mai mult gunoi inutil. (O gamă mică de numere întregi este stocată în memoria cache și accesul printr-un acces la matrice.) Poate că designerii de limbi au vrut să descurajeze această utilizare din motive de performanță.

Editați: Aș aprecia dacă downvoterul va comenta despre motivul pentru care acest lucru nu este de ajutor.

0
adăugat
Îmi doresc ca toți alegătorii să comenteze de ce a votat ceva. Mereu fac doar daca este evident (ca raspunsul este complet gresit sau prostii).
adăugat autor Jason Coco, sursa
Probabil că a fost votat de oameni care tocmai au citit biții de cod și au crezut că susțineți un astfel de cod.
adăugat autor Kris, sursa

pare a fi un neajuns   specificați-mi pentru mine

Există mai multe neajunsuri și acesta este un subiect subtil. Consultați acest :

public class methodOverloading{
   public static void hello(Integer x){
      System.out.println("Integer");
   }

   public static void hello(long x){
      System.out.println("long");
   }

   public static void main(String[] args){
      int i = 5;
      hello(i);
   }
}

Aici va fi tipărit "lung" (nu am verificat-o eu), deoarece compilatorul alege să se lărgească peste autoboxing. Fiți atent atunci când utilizați autoboxing sau nu-l utilizați deloc!

0
adăugat

După cum a subliniat toată lumea, autoboxing vă permite să simplificați un anumit cod, dar nu puteți preface că primitivele sunt tipuri complexe.

De asemenea, interesant: "autoboxing este un hack la nivel de compilator" în Java. Autoboxing-ul este, în esență, o ciudată cludge adăugată pe Java. Consultați acest post pentru mai multe detalii despre cât de ciudat este .

0
adăugat

În C#, numerele întregi nu sunt nici tipuri de referință și nici nu trebuie să fie în cutie pentru ca ToString() să fie apelate. Acestea sunt considerate obiecte din cadrul Cadrului (ca un ValueType, deci au o semantică de valoare). În CLR, metodele pe primitive sunt numite prin "indirect" încărcarea lor pe stivă (ldind).

0
adăugat

O altă modalitate de a face acest lucru este de a utiliza:

String.valueOf(myInt);

Această metodă este supraîncărcată pentru fiecare tip primitiv și Object . În acest fel, nici măcar nu trebuie să vă gândiți la tipul pe care îl utilizați. Implementările metodei vor numi metoda potrivită pentru tipul dat pentru dvs., de ex. Integer.toString (Myint) .

Consultați http://java.sun.com/javase/ 6 / docs / api / java / lang / String.html .

0
adăugat