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 vagy . a neve nem tartalmazhatja a karaktereket "<» и «>”.

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 és hogy a JVM ellenőrizze, hogy egy konstruktor egy másik érvényes konstruktort hív.

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.