AbstractMethodError Java-ban
1. Áttekintés
Néha találkozhatunk AbstractMethodError futás közben az alkalmazásunkban. Ha nem ismerjük jól ezt a hibát, eltarthat egy ideig, amíg meghatározzuk a probléma okát.
Ebben az oktatóanyagban alaposabban megvizsgáljuk AbstractMethodError. Megértjük mit AbstractMethodError és mikor történhet meg.
2. Bevezetés a AbstractMethodError
AbstractMethodError akkor kerül dobásra, amikor egy alkalmazás megpróbál meghívni egy nem megvalósított absztrakt módszert.
Tudjuk, hogy ha vannak megvalósítatlan elvont módszerek, akkor a fordító fog először panaszkodni. Ezért az alkalmazás egyáltalán nem épül fel.
Megkérdezhetjük, hogyan érhetjük el ezt a hibát futás közben?
Először nézzük meg, hol AbstractMethodError illeszkedik a Java kivétel hierarchiájába:
java.lang.Object | _java.lang.Throwable | _java.lang.Error | _java.lang.LinkageError | _java.lang.IncompatibleClassChangeError | _java.lang.AbstractMethodError
Amint a fenti hierarchia mutatja, ez a hiba a IncompatibleClassChangeError. Ahogy a szülőosztály neve is mutatja, AbstractMethodError általában akkor dobják le, ha inkompatibilitások vannak a lefordított osztályok vagy JAR fájlok között.
Ezután értsük meg, hogyan történhet ez a hiba.
3. Hogyan fordulhat elő ez a hiba
Amikor építünk egy alkalmazást, általában importálunk néhány könyvtárat, hogy megkönnyítsük a munkánkat.
Tegyük fel, hogy alkalmazásunkban a baeldung-sor könyvtár. A baeldung-sor library egy magas szintű specifikációs könyvtár, amely csak egy interfészt tartalmaz:
nyilvános felület BaeldungQueue {void enqueue (Object o); Object dequeue (); }
Továbbá a BaeldungQueue felületen importálunk egy BaeldungQueue megvalósítási könyvtár: jó sor. A jó sor a könyvtárnak is csak egy osztálya van:
public class GoodQueue implementálja a BaeldungQueue {@Orride public void enqueue (Object o) {// implementáció} @Override public Object dequeue () {// implementáció}}
Most, ha mindkettő jó sor és baeldung-sor osztályosztályban vannak, létrehozhatunk egy BaeldungQueue például az alkalmazásunkban:
public class Alkalmazás {BaeldungQueue queue = new GoodQueue (); public void someMethod (Objektum elem) {queue.enqueue (elem); // ... queue.dequeue (); // ...}}
Eddig jó.
Egyszer ezt megtanultuk baeldung-sor kiadott verzió 2.0 és hogy új módszerrel szállítja:
nyilvános felület BaeldungQueue {void enqueue (Object o); Object dequeue (); int méret (); }
Szeretnénk használni az újat méret() módszer alkalmazásunkban. Ezért frissítjük a baeldung-sor könyvtárból 1.0 nak nek 2.0. Azt azonban elfelejtettük ellenőrizni, hogy van-e a jó sor könyvtárat, amely megvalósítja a BaeldungQueue az interfész változásai.
Ezért van jó várólista 1.0 és baeldung-queue 2.0 az osztályúton.
Továbbá elkezdjük használni az új módszert alkalmazásunkban:
public class Alkalmazás {BaeldungQueue queue = new GoodQueue (); public void someMethod (Object element) {// ... int size = queue.size (); // <- az AbstractMethodError fel lesz dobva // ...}}
Kódunkat minden probléma nélkül összeállítjuk.
Amikor azonban a vonal queue.size () futás közben kerül végrehajtásra, an AbstractMethodError dobni fogják. Ez azért van, mert a jó sor1.0 könyvtár nem valósítja meg a módszert méret() ban,-ben BaeldungQueue felület.
4. Valóságpélda
Az egyszerűn keresztül BaeldungQueue és GoodQueue forgatókönyv szerint felmerülhet az ötlet, amikor egy alkalmazás dobhat AbstractMethodError.
Ebben a szakaszban egy gyakorlati példát fogunk látni AbstractMethodError.
java.sql.Connection fontos felület a JDBC API-ban. Az 1.7-es verzió óta számos új módszer került fel a Kapcsolat interfész, például getSchema ().
A H2 adatbázis elég gyors, nyílt forráskódú SQL adatbázis. A verzió óta 1.4.192, hozzáadta a java.sql.Connection.getSchema () módszer. A korábbi verziókban azonban a H2 adatbázis még nem alkalmazta ezt a módszert.
Ezután felhívjuk a java.sql.Connection.getSchema () módszer egy Java 8 alkalmazásból egy régebbi H2 adatbázis-verzióra 1.4.191. Lássuk, mi fog történni.
Hozzunk létre egy unit-test osztályt annak ellenőrzésére, hogy meghívjuk-e a Connection.getSchema () módszer dobni fog AbstractMethodError:
class AbstractMethodErrorUnitTest {private static final String url = "jdbc: h2: mem: A-DATABASE; INIT = Séma létrehozása, ha nem létezik myschema"; privát statikus végső String felhasználónév = "sa"; @Test void givenOldH2Database_whenCallgetSchemaMethod_thenThrowAbstractMethodError () dobja az SQLException {Connection conn = DriverManager.getConnection (URL, felhasználónév, ""); assertNotNull (conn); Assertions.assertThrows (AbstractMethodError.class, () -> conn.getSchema ()); }}
Ha lefuttatjuk a tesztet, akkor az sikeres lesz, megerősítve, hogy a hívás getSchema () dob AbstractMethodError.
5. Következtetés
Néha láthatjuk AbstractMethodError futás közben. Ebben a cikkben példákkal ismertettük, hogy a hiba mikor fordul elő.
Amikor alkalmazásunk egyik könyvtárát frissítjük, mindig jó gyakorlat ellenőrizni, hogy más függőségek használják-e a könyvtárat, és fontolja meg a kapcsolódó függőségek frissítését.
Másrészt, ha egyszer szembesülünk AbstractMethodError, ennek a hibának a megértésével gyorsan megoldhatjuk a problémát.
Mint mindig, a cikk teljes forráskódja elérhető a GitHubon.