AbstractMethodError u Javi

1. Pregled

Ponekad se možemo susresti AbstractMethodError za vrijeme izvođenja u našoj aplikaciji. Ako ovu pogrešku ne poznajemo dobro, možda će trebati neko vrijeme da utvrdimo uzrok problema.

U ovom uputstvu detaljnije ćemo pogledati AbstractMethodError. Shvatit ćemo što AbstractMethodError jest i kada se to može dogoditi.

2. Uvod u AbstractMethodError

AbstractMethodError baca se kada aplikacija pokušava nazvati neprimijenjenu apstraktnu metodu.

Znamo da će se, ako postoje neprimjenjene apstraktne metode, prvo žaliti sastavljač. Stoga se aplikacija uopće neće graditi.

Možemo se pitati kako možemo doći do ove pogreške tijekom izvođenja?

Prvo, pogledajmo gdje AbstractMethodError uklapa se u hijerarhiju Java iznimke:

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

Kao što gornja hijerarhija pokazuje, ova je pogreška podrazred IncompatibleClassChangeError. Kao što naziv njegove roditeljske klase implicira, AbstractMethodError obično se baca kada postoje nekompatibilnosti između prevedenih klasa ili JAR datoteka.

Dalje, shvatimo kako se ova pogreška može dogoditi.

3. Kako se ova pogreška može dogoditi

Kad gradimo aplikaciju, obično uvozimo neke knjižnice kako bismo si olakšali posao.

Recimo, u našu prijavu uključujemo a baeldung-red knjižnica. The baeldung-red knjižnica je knjižnica specifikacija visoke razine koja sadrži samo jedno sučelje:

javno sučelje BaeldungQueue {void enqueue (Objekt o); Dequeue objekta (); } 

Također, koristiti BaeldungQueue sučelje, uvozimo a BaeldungQueue knjižnica implementacije: red u redu. The red u redu knjižnica također ima samo jedan razred:

javna klasa GoodQueue implementira BaeldungQueue {@Override javni void enqueue (Object o) {// implementacija} @Override public Obque dequeue () {// implementacija}} 

Sad, ako oboje red u redu i baeldung-red su u stazi, možemo stvoriti BaeldungQueue primjer u našoj aplikaciji:

aplikacija javne klase {BaeldungQueue queue = new GoodQueue (); javna void someMethod (element objekta) {queue.enqueue (element); // ... queue.dequeue (); // ...}} 

Zasada je dobro.

Jednog dana, to smo naučili baeldung-red objavljena verzija 2.0 i da se isporučuje s novom metodom:

javno sučelje BaeldungQueue {void enqueue (Objekt o); Dequeue objekta (); int veličina (); } 

Želimo koristiti novo veličina() metoda u našoj aplikaciji. Stoga nadograđujemo baeldung-red knjižnica iz 1.0 do 2.0. Međutim, zaboravljamo provjeriti postoji li nova verzija red u redu knjižnica koja provodi BaeldungQueue promjene sučelja.

Stoga imamo red u redu 1,0 i baeldung-red 2.0 u razrednoj stazi.

Nadalje, počinjemo koristiti novu metodu u našoj aplikaciji:

javna klasa Application {BaeldungQueue queue = new GoodQueue (); javna void someMethod (element objekta) {// ... int size = queue.size (); // <- Izbacit će se AbstractMethodError // ...}} 

Naš će se kôd sastaviti bez ikakvih problema.

Međutim, kad crta queue.size () izvršava se u vrijeme izvođenja, an AbstractMethodError bit će bačen. To je zato što red u redu1.0 knjižnica ne primjenjuje metodu veličina() u BaeldungQueue sučelje.

4. Primjer iz stvarnog svijeta

Kroz jednostavno BaeldungQueue i Dobar red scenariju, možda ćemo dobiti ideju kada aplikacija može baciti AbstractMethodError.

U ovom ćemo odjeljku vidjeti praktični primjer AbstractMethodError.

java.sql.Connection je važno sučelje u JDBC API-ju. Od verzije 1.7, nekoliko novih metoda dodano je u Veza sučelje, kao što je getSchema ().

Baza podataka H2 prilično je brza SQL baza podataka otvorenog koda. Od verzije 1.4.192, dodao je podršku java.sql.Connection.getSchema () metoda. Međutim, u prethodnim verzijama baza podataka H2 još nije implementirala ovu metodu.

Dalje ćemo nazvati java.sql.Connection.getSchema () metoda iz aplikacije Java 8 na starijoj verziji baze podataka H2 1.4.191. Da vidimo što će se dogoditi.

Stvorimo klasu unit-test da provjerimo pozivamo li Connection.getSchema () metoda će baciti AbstractMethodError:

class AbstractMethodErrorUnitTest {private static final String url = "jdbc: h2: mem: A-DATABASE; INIT = IZRADI ŠEMU AKO NE POSTOJI myschema"; privatni statički konačni niz Korisničko ime = "sa"; @Test void givenOldH2Database_whenCallgetSchemaMethod_thenThrowAbstractMethodError () baca SQLException {Connection conn = DriverManager.getConnection (url, korisničko ime, ""); assertNotNull (conn); Assertions.assertThrows (AbstractMethodError.class, () -> conn.getSchema ()); }} 

Ako pokrenemo test, proći će, potvrđujući da je poziv na getSchema () baca AbstractMethodError.

5. Zaključak

Ponekad možemo vidjeti AbstractMethodError za vrijeme izvođenja. U ovom smo članku kroz primjere razgovarali o pogrešci.

Kada nadogradimo jednu knjižnicu naše aplikacije, uvijek je dobra praksa provjeriti koriste li druge ovisnosti knjižnicu i razmislite o ažuriranju povezanih ovisnosti.

S druge strane, kad se jednom suočimo AbstractMethodError, s dobrim razumijevanjem ove pogreške, možemo brzo riješiti problem.

Kao i uvijek, puni izvorni kôd članka dostupan je na GitHub-u.


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