AbstractMethodError v Jave

1. Prehľad

Niekedy sa môžeme stretnúť AbstractMethodError za behu v našej aplikácii. Ak túto chybu dobre nepoznáme, zistenie príčiny problému môže chvíľu trvať.

V tomto tutoriáli sa pozrieme bližšie AbstractMethodError. Pochopíme čo AbstractMethodError je a kedy sa to môže stať.

2. Úvod do AbstractMethodError

AbstractMethodError sa vyvolá, keď sa aplikácia pokúsi zavolať neimplementovanú abstraktnú metódu.

Vieme, že ak existujú neimplementované abstraktné metódy, kompilátor sa najskôr sťažuje. Aplikácia sa preto vôbec nevytvorí.

Môžeme sa spýtať, ako môžeme dostať túto chybu za behu?

Najprv sa pozrime, kam AbstractMethodError zapadá do hierarchie výnimiek Java:

java.lang.Object | _java.lang.Throwable | _java.lang.Error | _java.lang.LinkageError | _java.lang.IncompatibleClassChangeError | _java.lang.AbstractMethodError

Ako ukazuje vyššie uvedená hierarchia, táto chyba je podtriedou IncompatibleClassChangeError. Ako už z názvu jej materskej triedy vyplýva, AbstractMethodError sa obvykle hodí, keď existujú kompilácie medzi kompilovanými triedami alebo súbormi JAR.

Ďalej pochopme, ako sa táto chyba môže stať.

3. Ako sa môže stať táto chyba

Keď zostavujeme aplikáciu, zvyčajne naimportujeme niektoré knižnice, ktoré nám uľahčia prácu.

Povedzme, že do našej aplikácie zahrňujeme a baeldung-fronta knižnica. The baeldung-fronta Knižnica je knižnica špecifikácií vysokej úrovne, ktorá obsahuje iba jedno rozhranie:

verejné rozhranie BaeldungQueue {void enqueue (Objekt o); Zoradenie objektov (); } 

Tiež použiť BaeldungQueue rozhranie, importujeme a BaeldungQueue knižnica implementácie: dobrý rad. The dobrý rad knižnica má tiež iba jednu triedu:

verejná trieda GoodQueue implementuje BaeldungQueue {@Override public void enqueue (Object o) {// implementation} @Override public Object dequeue () {// implementation}} 

Teraz, ak obaja dobrý rad a baeldung-fronta sú v triede, môžeme vytvoriť BaeldungQueue napríklad v našej aplikácii:

verejná trieda Aplikácia {BaeldungQueue queue = nová GoodQueue (); public void someMethod (Object element) {queue.enqueue (element); // ... queue.dequeue (); // ...}} 

Zatiaľ je všetko dobré.

Jedného dňa sme sa to naučili baeldung-fronta vydaná verzia 2.0 a že sa dodáva s novou metódou:

verejné rozhranie BaeldungQueue {void enqueue (Object o); Zoradenie objektov (); int velkost (); } 

Chceme použiť nové veľkosť () metóda v našej aplikácii. Preto inovujeme baeldung-fronta knižnica z 1.0 do 2.0. Zabúdame však skontrolovať, či existuje nová verzia aplikácie dobrý rad knižnica, ktorá implementuje BaeldungQueue zmeny rozhrania.

Preto máme dobrý rad 1.0 a baeldung-fronta 2.0 v triede.

Ďalej začneme používať novú metódu v našej aplikácii:

verejná trieda Aplikácia {BaeldungQueue queue = nová GoodQueue (); public void someMethod (Object element) {// ... int size = queue.size (); // <- Bude vyhodená AbstractMethodError // ...}} 

Náš kód bude zostavený bez akýchkoľvek problémov.

Keď však linka queue.size () sa vykonáva za behu, AbstractMethodError bude vyhodený. Je to preto, lebo dobrý rad1.0 knižnica metódu neimplementuje veľkosť () v BaeldungQueue rozhranie.

4. Príklad zo skutočného sveta

Prostredníctvom jednoduchého BaeldungQueue a GoodQueue scenár, môžeme získať nápad, kedy môže aplikácia hádzať AbstractMethodError.

V tejto časti uvidíme praktický príklad AbstractMethodError.

java.sql.Connection je dôležité rozhranie v JDBC API. Od verzie 1.7 bolo do systému pridaných niekoľko nových metód Pripojenie rozhranie, ako napr getSchema ().

Databáza H2 je dosť rýchla open-source databáza SQL. Od verzie 1.4.192, pridala podporu java.sql.Connection.getSchema () metóda. V predchádzajúcich verziách však databáza H2 túto metódu zatiaľ neimplementovala.

Ďalej zavoláme java.sql.Connection.getSchema () metóda z aplikácie Java 8 na staršej verzii databázy H2 1.4.191. Uvidíme, čo bude.

Vytvorme triedu testovania jednotiek na overenie, či sa volá Connection.getSchema () metóda bude hádzať AbstractMethodError:

class AbstractMethodErrorUnitTest {private static final String url = "jdbc: h2: mem: A-DATABASE; INIT = VYTVORIŤ SCHÉMU, AK NEEXISTUJE myschema"; private static final String username = "sa"; @Test void givenOldH2Database_whenCallgetSchemaMethod_thenThrowAbstractMethodError () hodí SQLException {Connection conn = DriverManager.getConnection (url, username, ""); assertNotNull (conn); Assertions.assertThrows (AbstractMethodError.class, () -> conn.getSchema ()); }} 

Ak vykonáme test, prejde a potvrdí, že hovor na getSchema () hodí AbstractMethodError.

5. Záver

Niekedy sa možno dočkáme AbstractMethodError za behu. V tomto článku sme na príkladoch diskutovali o tom, kedy k chybe dôjde.

Keď inovujeme jednu knižnicu našej aplikácie, vždy je dobrým zvykom skontrolovať, či knižnicu používajú iné závislosti, a zvážiť aktualizáciu súvisiacich závislostí.

Na druhej strane, raz čelíme AbstractMethodError, s dobrým porozumením tejto chyby, môžeme problém rýchlo vyriešiť.

Celý zdrojový kód článku je ako vždy k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found