AbstractMethodError i Java

1. Oversikt

Noen ganger kan vi møte AbstractMethodError ved kjøretid i søknaden vår. Hvis vi ikke kjenner denne feilen godt, kan det ta litt tid å finne årsaken til problemet.

I denne opplæringen vil vi se nærmere på AbstractMethodError. Vi forstår hva AbstractMethodError er og når det kan skje.

2. Introduksjon til AbstractMethodError

AbstractMethodError kastes når et program prøver å kalle en ikke-implementert abstrakt metode.

Vi vet at hvis det er uimplementerte abstrakte metoder, vil kompilatoren først klage. Derfor blir applikasjonen ikke bygget i det hele tatt.

Vi kan spørre hvordan vi kan få denne feilen ved kjøretid?

La oss først se på hvor AbstractMethodError passer inn i Java-unntakshierarkiet:

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

Som hierarkiet ovenfor viser, er denne feilen en underklasse av InkompatibelClassChangeError. Som foreldreklassens navn tilsier, AbstractMethodError blir vanligvis kastet når det er inkompatibilitet mellom kompilerte klasser eller JAR-filer.

La oss nå forstå hvordan denne feilen kan skje.

3. Hvordan denne feilen kan oppstå

Når vi bygger en applikasjon, importerer vi vanligvis noen biblioteker for å gjøre arbeidet vårt enklere.

La oss si at i søknaden vår inkluderer vi a baeldung-kø bibliotek. De baeldung-kø biblioteket er et høyt nivå spesifikasjonsbibliotek, som bare inneholder ett grensesnitt:

offentlig grensesnitt BaeldungQueue {void enqueue (Object o); Objekt dequeue (); } 

Også å bruke BaeldungQueue grensesnitt importerer vi en BaeldungQueue implementeringsbibliotek: god kø. De god kø biblioteket har også bare en klasse:

offentlig klasse GoodQueue implementerer BaeldungQueue {@ Override public void enqueue (Object o) {// implementering} @ Override public Object dequeue () {// implementering}} 

Nå, hvis begge deler god kø og baeldung-kø er i klassestien, kan vi opprette en BaeldungQueue eksempel i søknaden vår:

public class Application {BaeldungQueue queue = new GoodQueue (); offentlig ugyldig someMethod (Object element) {queue.enqueue (element); // ... kø.dequeue (); // ...}} 

Så langt så bra.

En dag har vi lært det baeldung-kø utgitt versjon 2.0 og at den sendes med en ny metode:

offentlig grensesnitt BaeldungQueue {void enqueue (Object o); Objekt dequeue (); int størrelse (); } 

Vi vil bruke det nye størrelse() metode i søknaden vår. Derfor oppgraderer vi baeldung-kø bibliotek fra 1.0 til 2.0. Vi glemmer imidlertid å sjekke om det er en ny versjon av god kø biblioteket som implementerer BaeldungQueue grensesnittendringer.

Derfor har vi god kø 1.0 og baeldung-kø 2.0 i klassestien.

Videre begynner vi å bruke den nye metoden i applikasjonen vår:

public class Application {BaeldungQueue queue = new GoodQueue (); offentlig ugyldig someMethod (Object element) {// ... int size = queue.size (); // <- AbstractMethodError vil bli kastet // ...}} 

Koden vår blir samlet uten problemer.

Imidlertid når linjen kø.størrelse () utføres ved kjøretid, og AbstractMethodError vil bli kastet. Dette er fordi god kø1.0 biblioteket implementerer ikke metoden størrelse() i BaeldungQueue grensesnitt.

4. Et ekteeksempel

Gjennom det enkle BaeldungQueue og GoodQueue scenario, kan vi få ideen når en applikasjon kan kaste AbstractMethodError.

I denne delen ser vi et praktisk eksempel på AbstractMethodError.

java.sql.Tilkobling er et viktig grensesnitt i JDBC API. Siden versjon 1.7 har flere nye metoder blitt lagt til Forbindelse grensesnitt, for eksempel getSchema ().

H2-databasen er en ganske rask SQL-database med åpen kildekode. Siden versjon 1.4.192, det har lagt til støtte fra java.sql.Connection.getSchema () metode. I tidligere versjoner har H2-databasen imidlertid ikke implementert denne metoden ennå.

Deretter vil vi kalle java.sql.Connection.getSchema () metode fra et Java 8-program på en eldre H2-databaseversjon 1.4.191. La oss se hva som vil skje.

La oss lage en enhetstestklasse for å verifisere om vi ringer til Connection.getSchema () metoden vil kaste AbstractMethodError:

class AbstractMethodErrorUnitTest {private static final String url = "jdbc: h2: mem: A-DATABASE; INIT = CREATE SCHEMA IF NOT EXISTS myschema"; privat statisk slutt String brukernavn = "sa"; @Test ugyldig gittOldH2Database_whenCallgetSchemaMethod_thenThrowAbstractMethodError () kaster SQLException {Connection conn = DriverManager.getConnection (url, brukernavn, ""); assertNotNull (conn); Assertions.assertThrows (AbstractMethodError.class, () -> conn.getSchema ()); }} 

Hvis vi kjører testen, vil den bestå, og bekrefte at samtalen til getSchema () kaster AbstractMethodError.

5. Konklusjon

Noen ganger kan vi se AbstractMethodError ved kjøretid. I denne artikkelen har vi diskutert når feilen oppstår gjennom eksempler.

Når vi oppgraderer ett bibliotek i applikasjonen vår, er det alltid en god praksis å sjekke om andre avhengigheter bruker biblioteket, og vurdere å oppdatere de relaterte avhengighetene.

På den annen side, når vi møter AbstractMethodError, med god forståelse av denne feilen, kan vi løse problemet raskt.

Som alltid er hele kildekoden til artikkelen tilgjengelig på GitHub.


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