AbstractMethodError i Java

1. Oversigt

Nogle gange kan vi støde på AbstractMethodError ved kørselstid i vores ansøgning. Hvis vi ikke kender denne fejl godt, kan det tage et stykke tid at finde årsagen til problemet.

I denne vejledning ser vi nærmere på AbstractMethodError. Vi forstår hvad AbstractMethodError er, og hvornår det kan ske.

2. Introduktion til AbstractMethodError

AbstractMethodError kastes, når en applikation forsøger at kalde en uimplementeret abstrakt metode.

Vi ved, at hvis der er uimplementerede abstrakte metoder, vil compileren først klage. Derfor bliver applikationen slet ikke bygget.

Vi kan spørge, hvordan vi kan få denne fejl under kørsel?

Lad os først se på hvor AbstractMethodError passer ind i Java-undtagelseshierarkiet:

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

Som hierarkiet ovenfor viser, er denne fejl en underklasse af IncompatibleClassChangeError. Som dets overordnede klasses navn antyder, AbstractMethodError kastes normalt, når der findes uoverensstemmelser mellem kompilerede klasser eller JAR-filer.

Lad os derefter forstå, hvordan denne fejl kan ske.

3. Hvordan denne fejl kan ske

Når vi bygger en applikation, importerer vi normalt nogle biblioteker for at gøre vores arbejde lettere.

Lad os sige, i vores ansøgning inkluderer vi en baeldung-kø bibliotek. Det baeldung-kø bibliotek er et specifikationsbibliotek på højt niveau, der kun indeholder en grænseflade:

offentlig grænseflade BaeldungQueue {void enqueue (Object o); Objekt dequeue (); } 

Også for at bruge BaeldungQueue interface importerer vi en BaeldungQueue implementeringsbibliotek: god kø. Det god kø biblioteket har også kun en klasse:

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

Nu, hvis begge dele god kø og baeldung-kø er i klassestien, kan vi oprette en BaeldungQueue eksempel i vores ansøgning:

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

Så langt så godt.

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

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

Vi vil bruge det nye størrelse() metode i vores ansøgning. Derfor opgraderer vi baeldung-kø bibliotek fra 1.0 til 2.0. Vi glemmer dog at kontrollere, om der er en ny version af god kø bibliotek, der implementerer BaeldungQueue interface ændringer.

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

Desuden begynder vi at bruge den nye metode i vores applikation:

public class Application {BaeldungQueue queue = new GoodQueue (); public void someMethod (Object element) {// ... int size = queue.size (); // <- AbstractMethodError smides // ...}} 

Vores kode bliver kompileret uden problemer.

Men når linjen kø.størrelse () udføres ved kørsel, og AbstractMethodError vil blive kastet. Dette skyldes, at god kø1.0 biblioteket implementerer ikke metoden størrelse() i BaeldungQueue interface.

4. Et virkeligt verdenseksempel

Gennem det enkle BaeldungQueue og GoodQueue scenarie, kan vi få ideen, når en applikation kan kaste AbstractMethodError.

I dette afsnit ser vi et praktisk eksempel på AbstractMethodError.

java.sql.Tilslutning er en vigtig grænseflade i JDBC API. Siden version 1.7 er der tilføjet flere nye metoder til Forbindelse interface, f.eks getSchema ().

H2-databasen er en ret hurtig SQL-database med open source. Siden version 1.4.192, det har tilføjet støtte fra java.sql.Connection.getSchema () metode. I tidligere versioner har H2-databasen dog ikke implementeret denne metode endnu.

Derefter kalder vi java.sql.Connection.getSchema () metode fra et Java 8-program på en ældre H2-databaseversion 1.4.191. Lad os se, hvad der vil ske.

Lad os oprette en enhedstestklasse for at kontrollere, om vi ringer til Connection.getSchema () metoden vil kaste AbstractMethodError:

klasse AbstractMethodErrorUnitTest {privat statisk endelig String url = "jdbc: h2: mem: A-DATABASE; INIT = OPRET SKEMA HVIS IKKE eksisterer myschema"; privat statisk endelig streng brugernavn = "sa"; @Test ugyldigt givenOldH2Database_whenCallgetSchemaMethod_thenThrowAbstractMethodError () kaster SQLException {Connection conn = DriverManager.getConnection (url, brugernavn, ""); assertNotNull (konn); Assertions.assertThrows (AbstractMethodError.class, () -> conn.getSchema ()); }} 

Hvis vi kører testen, vil den bestå og bekræfte, at opkaldet til getSchema () kaster AbstractMethodError.

5. Konklusion

Nogle gange kan vi se AbstractMethodError ved kørselstid. I denne artikel har vi diskuteret, hvornår fejlen opstår gennem eksempler.

Når vi opgraderer et bibliotek i vores applikation, er det altid en god praksis at kontrollere, om andre afhængigheder bruger biblioteket og overveje at opdatere de relaterede afhængigheder.

På den anden side, når vi først står over for AbstractMethodError, med en god forståelse af denne fejl, kan vi muligvis løse problemet hurtigt.

Som altid er artiklens fulde kildekode tilgængelig på GitHub.


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