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.