Java WTF

Wikipédián találtam:

Autoboxing is incomplete and can never be fully or properly implemented without operator overloading.

For example:

Integer a = 2;
Integer b = 2;
Integer c = 2000;
Integer d = 2000;

if ( a == b ) { /* this block will execute */ }
if ( c == d ) { /* this block WON'T execute! */ }

127-ig (byte) működik az ==, utána már csak az equals jó. De egyáltalán miért működik, és miért 127-ig?

Hozzászólások

Mert az == az a referenciakat hasonlitja ossze, a rendes, tipusbiztos osszehasonlitasra az equals() valo. Hasznalj equals()-t mindig, es nem lesz problemad.

Vmi olyasmi van, hogy 127-ig van neki minden Integerbol 1-1 peldanya, es ha letrehozol egyet, akkor az ezek egyikere lesz referencia, mig 127 folott letrehozott Integer uj objektum lesz.

miert is lenne ettol incomplete? JLSben benne van feketen, feheren, hogy 127ig az IntegerCachebol jonnek a dolgok.

Az == az nyelvi elem. Definialva van, hogy mikepp mukodik. Abban semmi koncepcio nincs, hogy egyik osztalyra ezt jelenti, masik osztalyra meg azt. Az autoboxing is specifikalva van, hogy mit jelent es mikepp mukodik. Tudni kell, hogy amit leirsz, mit jelent, ennyi az egesz. Es ez minden programozasi nyelvre igy van.
Az Integer objektum, nem is mas. 1.0 ota resze a Java-nak. Autoboxing meg 5.0 ota van. Senki nem mondta soha, hogy igazi doboza lesz az Integer az int-nek, mivel akkor torni kene a visszafele valo kompatibilitast (ezert is tipustorlessel valosul meg a generic adat, nem mashogy, mert az torest okozna).

uderonda igy leirni hogy "tores"... meg doboz.. OMG :)

az, hogy az int boxolodik-e az Integerre, vagy nem, az nem dobozolas, meg backward-compatibility kerdes, szerintem. a boxolas csak szelesitette azoknak a kodoknak a halmazat, amik legalis java kodok lettek, szoval egyaltalan semmi koze a type erasurehoz.

C++-t akartam mondani, no.

Úgy jön ide, hogy a Wikipedia említette az operator overloading-ot. Úgy is ide jön, hogy a Java fejlődésére hatással volt a C# megjelenése, amiben szintén van (és az autoboxing a C# megjelenése után (mintájára?) került a Java-ba, ha az olvasottakat helyesen értelmeztem).

Igen, viszont Java-ban meg mindig int != Integer. Bar van automatikus konverzio, ettol nem egyenloek. Mint ahogy peldaul a new String("hello") != new String("hello"). Igazabol az okoz itt felreertest, hogy az IntegerCache-bol jovo Integer objektumok egyenloek egymassal, a tobbi pedig nem. Java-ban a == nyelvi elem ugyanis a kovit jelenti:
1) Ha az atadott referencia primitiv tipusu, akkor csak is akkor ad vissza igazat, ha a ket ertek megegyezik. (Gyanitom, hogy primitiv tipusok eseteben az ertekeket lerangatja nativ kodba, csinal egy C szintu osszehasonlitast, az eredmenyt pedig felnyomja. Jo, ez igy most durva megfogalmazas volt, de kb.)
2) Ha az adott referencia String konstans (nem new String() hivassal adtuk meg a string erteket) akkor karakterenkent ellenorzi, es akkor es csak is akkor ad vissza igazat, ha nem kulonbozik a ket string
3) Minden mas esetben meghivja az equals() fuggvenyt, es ennek visszateresi ertekevel ter vissza. Ez legrosszabb esetben az Object beli equals() megvalositas, ami meghivja a ket objektum hashCode() fuggvenyet, ami primitiv tipust (egeszet) ad vissza, melyek osszehasonlitasa ismert (1-es szamu eset).

A cache-bol jovo Integer objektumok meg azert egyenloek, mert mindig ugyanazok jonnek vissza a cache-bol. Szerintem ezt valahogy meg kellene oldani, mert eleg felreertheto...
Mindenesetre ettol a == operator ertelemezese nem valtozik meg, csak a cache kavar be.

Operator overloading pedig nem kell, foleg az == -hoz nem kell, mert azt pont az equals()/hashCode() fuggveny felulvagasaval lehet manipulalni.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

ajaj, ne terjessz baromsagot legyszi. a "==" SOSEM fogja neked meghivni az equalst. soha.

az 1, igaz; a 2 es a 3 baromsag. a Stringek nem azert egyenloek, mert ugyanazok, hanem azert egyenloek, mert ugyanarra az objektumra mutatnak, mivel a string literalok immutablek, es mindegyikbol csak egy letezik (ha nem new String() -el hozod letre).

a JLS idevago reszet tessek elolvasni. az == akkor ad vissza igazat ket objektum eseten, ha ugyanarra mutatnak. semikor maskor. ha az egyik primitiv tipus, akkor boxing tortenik, es ugy tortenik az ellenorzes.

Oke, de akkor az int cache dolog miert van? Mert ez kavarja meg az embereket (Integer(255) != Integer(255) -tel). Marmint, azt ertem, hogy miert van, de miert nem lehet ezt valahogy megbizgatni?

Illetve, sztem nem teljesen autoboxing tortenik, mert primitiv tipusok eseten a 255 == 255 igaz lesz, ha rendesen felkonvertalna objektumba mindket erteket, akkor false lenne a vege, hiszen ket kulonbozo objektum szuletne - ugye Integer(255) != Integer(255) - marpedig definicio szerint ket kulonbozo objektum sosem egyenlo (egy ==-et latva nem lehet feltetelezni, hogy a ket ertek ugyanaz lesz, vagy akkor compiler szinten optimalizal?).

Amugy mondjuk ertelmesebb dolog lenne, ha equals-t hivna, hiszen ilyen metodusa mindenkinek van.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Azert van igy, mert a Java Language Specification ezt irja elo. PONT.
Autoboxing akkor tortenik, ha a kifejezes egyik oldala objektum (Integer, Double), a masik meg primitiv tipus. Ha a 255 == 255-t nezed, mindket oldal primitiv tipus, nincs autoboxing. Olvasd el a specifikaciot.

equals() metodusa pedig nincs mindennek. Foleg nem primitiv tipusoknak, null erteknek. Masreszt hogyan mondod meg, hogy ket valtozo a memoriaban fizikailag ugyanott van (ugyanaz a referenciaja), illetve azt, hogy ugyanazt az erteket tartalmazzak. Az egyikre valo az ==, a masikra az equals().
Mast jelent a ketto, tessek megerteni.

Ha igaz lenne, amit leirtal, akkor new String("hello") == new String("hello") lenne, mivel Stringekre letezik equals(), ami feluldefinialja az Object.equals()-t. Az == objektumreferenciat hasonlit ossze, azaz azt, hogy a JVM-ben fizikailag ugyanarrol az objektumrol van-e szo (ugyanott van a memoriaban).

A bejegyzésben pont azt kérdeztem hogy miért működik egyáltalán az ==, miért nem csak az equals. Egyébként tudom hogy akkor ad vissza igazat, ha ugyanarra az objektumra mutatnak.
Viszont ezt a Stringek közti különbséget nem tudtam. Így példányosítható osztályt én is tudok írni? (pl. Osztalyom a = 5)

Mint ahogy azt is jelenti, am Java-ban a primitivek nem egyenertekuek az oket reprezentalo osztalyokkal.

Ez a cache-s dolog sebessegoptimalizalas miatt jott letre ha jol tudom, semmi egyeb miatt. Mivel azonban itt objektumokrol van szo, normalis esetben nem is szabad tamaszkodni arra, hogy ket eltero peldany ekvivalens lehet egymassal. A legtobb esetben megszerezzuk az adott erteket, es ezzel szamolunk tovabb.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.