Nem elérhető a java bytecode nyelvi jellemzőiben
Miután sokáig dolgoztam a Java bytecode-mal, és elvégeztem egy kutatást ezen a területen, meg szeretném osztani az általam készített következtetéseket.
Futtatható a kódkonstrukcióban, mielőtt egy szuperkonstrukciót vagy egy kiegészítő konstruktort hív
A Java programozási nyelv, mint a (tovább - JPL, a Java programozási nyelv) hívja a super (), illetve ennek () kell az első utasítás a kivitelező, hanem a Java bytecode (a továbbiakban - JBC, a Java byte-kód) nem. A következő kódok hozzáadása előtt hozzáadhat kódot, ha az alábbi feltételek teljesülnek:
- egy másik konstruktort még mindig tovább neveznek;
- nem feltételes;
- Mielőtt felhívja a konstruktort, a mezők nem olvashatók, és nem hívják meg az épített objektum metódusát. Ebből következik a következő kérdés.
A (z) super () vagy ezt ()
A Java hatodik verzióját megelőzően a következő műveleteket használták fel:
Most a JPL-ben a mezőkkel végzett munkák lehetetlenek, de a JBC használatával továbbra is lehetséges.
A hívott konstruktor kiválasztása (Java 7u23 előtt)
A Java nem teszi lehetővé az ilyen konstrukterek létrehozását:
A Java 7u23 előtt azonban a HotSpot VM hitelesítője kihagyta ezt a csekket. Most már rögzített.
Egy osztály létrehozása egyáltalán nem konstruktorral
A JPL-ben ez nem lehetséges - legalább egy konstruktor, de mindig öröklött. A JBC használatával lehetetlenné teheti az osztály egy példányának létrehozását, még akkor is, ha reflexiót használ (bár a sun.misc.unsafe még mindig lehetővé teszi ezt).
Ugyanazon aláírású módszerek létrehozása, de különböző visszatérési típusok
A JPL-ben a módszereket a nevük és a paraméterek csoportja határozza meg, és a JBC-ben a módszereket is visszaadják.
Az ellenőrzött kivételek meghívása a dobások vagy a konstrukció megadásának megadása nélkül. fogás
Annak ellenőrzése, hogy az összes ellenőrzött kivételt elkapják-e (vagy a dobokkal jelöltek-e), végrehajtja-e a fordítót, nem függ a Java Runtime vagy a JBC típusától.
Dinamikus módszerrel történő hívás a lambda kifejezéseken kívül
Az úgynevezett dinamikus metódushívást bármihez alkalmazhatjuk, nem csak a lambda kifejezésekre. Használata például lehetővé teszi a program logikájának megváltoztatását a végrehajtás során. Sok, a JBC-n alapuló dinamikus programozási nyelv javult ennek az utasításnak köszönhetően. A JBC-ben a lambda kifejezéseket Java 7-ben is használhatjuk, amikor a fordító nem tudott dinamikus módszeres hívásokat kezelni, és a JVM is képes.
Általában tiltott azonosítók használata
Hozzáadott volna egy helyet vagy egy sortörést a módszer nevében? Hozzon létre JBC-t, és sikeres hibakeresést végezzen! Csak a ".", ";", "[" És "/" betűk vannak tiltva. Ezenkívül, ha a módszert nem hívják
A végleges mezők átirányítása, a végső paraméterek és ez
A JBC végső paramétere nem létezik, és bármely paraméter, beleértve ezt is (a zeroth indexben), megváltoztatható. Az állandó mező módosítható is, ha már definiáltuk a konstruktorban (ez nem kötelező a statikus mezőknél).
A módszer felhívása nullról
A JBC-ben bármely nem statikus módszert null-ba hívhat. és finom lesz, ha nem hívja ezt.
A konstruktorok és az inicializáló eszközök használata, mintha ezek a módszerek
A JBC-ben a konstruktorok és az inicializáló eszközök nem különböznek a módszertől, az egyetlen dolog az, hogy névnek kell lennie
Nem virtuális módszer hívja ugyanabból az osztályból
A JPL-ben az új Bar :: foo () hívás mindig felhívja a futásidejű kivételt. Nem tudja az Foo :: foo () metódus mindig felhívni a bar () osztályát. De ezt a viselkedést a JBC-n végrehajthatja az INVOKESPECIAL opcode használatával. amelyet általában a szülői módszerek hívására használnak.
Tetszőleges meta-attribútum hozzárendelése
A JPL-ben csak a mezőkre, módszerekre és osztályokra lehet bejegyzéseket felvenni. A JBC-ben bármely információt beilleszthet az osztályba. Azonban használatához önnek kell kitörölnie magát, anélkül, hogy támaszkodna a Java osztályok betöltésére szolgáló mechanizmusra.
A byte értékek túlcsordulása és implicit meghatározása. rövid. char és logikai
Technikailag csak int típusúak vannak a bytecode-ban. lebegnek. hosszú és kettős. ami számos JPL műveletre elfogadhatatlan.
Rekurzív fogásblokk
A Java bytecode-ban meg tudod csinálni valamit
Bármely "alapértelmezett módszer"
A JBC-ben az alapértelmezett módszert hívhatja, még akkor is, ha újra definiálták.
A szülő metódusának más objektumra való felhívása
A JPL-ben csak a legközelebbi szülő vagy alapértelmezett interfész módjait hívhatja meg. A JBC-ben ilyen kód lehetséges:
Hozzáférés a szintetikus tagokhoz
A bytecode-ban a szintetikus tagok közvetlenül elérhetõk.
Ez a szintetikus mezőkre, módszerekre és osztályokra is érvényes.
A generikumok helytelen információinak hozzáadása
A generikumokról szóló információk az osztályban sztringként vannak tárolva. A hitelesítő semmilyen módon nem ellenőrzi, így biztos lehet benne, hogy a következő állítások igazak:
A nem létező módszer felhívása és a JVM összeomlása
Bármilyen példányban bármelyik módszert hívhat. Általában a hitelesítő felismeri ezt, de észrevettem, hogy néha egy tömbelemre vonatkozó metódust hívnak, a JVM egyes verziói nem ismerik fel, hogy nem létezik. Ez természetesen kétséges lehetőség, de a kód segítségével, amely átment a javakon. ezt nem teheti meg. Persze, amikor a JVM eléri ezt a pontot, összeomlik.