AbstractMethodError in Java

1. Overzicht

Soms kunnen we tegenkomen AbstracteMethodeFout tijdens runtime in onze applicatie. Als we deze fout niet goed kennen, kan het even duren voordat de oorzaak van het probleem is vastgesteld.

In deze tutorial zullen we die nader bekijken AbstracteMethodeFout. We zullen begrijpen wat AbstracteMethodeFout is en wanneer het kan gebeuren.

2. Inleiding tot AbstracteMethodeFout

AbstracteMethodeFout wordt gegenereerd wanneer een toepassing probeert een niet-geïmplementeerde abstracte methode aan te roepen.

We weten dat als er niet-geïmplementeerde abstracte methoden zijn, de compiler eerst zal klagen. Daarom wordt de applicatie helemaal niet gebouwd.

We kunnen ons afvragen hoe we deze fout tijdens runtime kunnen krijgen?

Laten we eerst eens kijken waar AbstracteMethodeFout past in de Java-uitzonderingshiërarchie:

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

Zoals de bovenstaande hiërarchie laat zien, is deze fout een subklasse van IncompatibleClassChangeError. Zoals de naam van de bovenliggende klasse aangeeft, AbstracteMethodeFout wordt meestal gegenereerd als er incompatibiliteit bestaat tussen gecompileerde klassen of JAR-bestanden.

Laten we vervolgens eens kijken hoe deze fout kan optreden.

3. Hoe deze fout kan gebeuren

Wanneer we een applicatie bouwen, importeren we meestal enkele bibliotheken om ons werk gemakkelijker te maken.

Laten we zeggen dat we in onze applicatie een baeldung-wachtrij bibliotheek. De baeldung-wachtrij bibliotheek is een specificatiebibliotheek op hoog niveau, die slechts één interface bevat:

openbare interface BaeldungQueue {void enqueue (Object o); Object uit de wachtrij halen (); } 

Om ook de BaeldungQueue interface importeren we een BaeldungQueue implementatie bibliotheek: goede wachtrij. De goede wachtrij bibliotheek heeft ook maar één klasse:

public class GoodQueue implementeert BaeldungQueue {@Override public void enqueue (Object o) {// implementatie} @Override public Object dequeue () {// implementatie}} 

Nu, als beide goede wachtrij en baeldung-wachtrij zijn in het klassenpad, kunnen we een BaeldungQueue bijvoorbeeld in onze applicatie:

openbare klasse Applicatie {BaeldungQueue wachtrij = nieuwe GoodQueue (); public void someMethod (objectelement) {queue.enqueue (element); // ... queue.dequeue (); // ...}} 

Tot nu toe zo goed.

Op een dag hebben we dat geleerd baeldung-wachtrij vrijgegeven versie 2.0 en dat het wordt geleverd met een nieuwe methode:

openbare interface BaeldungQueue {void enqueue (Object o); Object uit de wachtrij halen (); int grootte (); } 

We willen het nieuwe gebruiken grootte() methode in onze applicatie. Daarom upgraden we het baeldung-wachtrij bibliotheek van 1.0 naar 2.0. We vergeten echter te controleren of er een nieuwe versie is van het goede wachtrij bibliotheek die het BaeldungQueue interface verandert.

Daarom hebben we goede wachtrij 1.0 en baeldung-wachtrij 2.0 in het klassenpad.

Verder gaan we de nieuwe methode gebruiken in onze applicatie:

openbare klasse Applicatie {BaeldungQueue wachtrij = nieuwe GoodQueue (); public void someMethod (Object element) {// ... int size = queue.size (); // <- AbstractMethodError zal worden gegenereerd // ...}} 

Onze code wordt probleemloos samengesteld.

Echter, wanneer de lijn queue.size () wordt uitgevoerd tijdens runtime, een AbstracteMethodeFout zal worden gegooid. Dit komt doordat de goede wachtrij1.0 bibliotheek implementeert de methode niet grootte() in de BaeldungQueue koppel.

4. Een voorbeeld uit de echte wereld

Door het simpele BaeldungQueue en GoodQueue scenario, kunnen we het idee krijgen wanneer een applicatie kan gooien AbstracteMethodeFout.

In deze sectie zullen we een praktisch voorbeeld zien van de AbstracteMethodeFout.

java.sql.Connection is een belangrijke interface in de JDBC API. Sinds versie 1.7 zijn er verschillende nieuwe methoden toegevoegd aan het Verbinding interface, zoals getSchema ().

De H2-database is een vrij snelle open-source SQL-database. Sinds versie 1.4.192, heeft het de ondersteuning van de java.sql.Connection.getSchema () methode. In eerdere versies heeft de H2-database deze methode echter nog niet geïmplementeerd.

Vervolgens noemen we het java.sql.Connection.getSchema () methode van een Java 8-toepassing op een oudere H2-databaseversie 1.4.191. Eens kijken wat er gaat gebeuren.

Laten we een unit-test-klasse maken om te controleren of het Connection.getSchema () methode zal gooien AbstracteMethodeFout:

class AbstractMethodErrorUnitTest {privé statische laatste String url = "jdbc: h2: mem: A-DATABASE; INIT = SCHEMA MAKEN INDIEN NIET BESTAAT myschema"; private static final String gebruikersnaam = "sa"; @Test ongeldig gegevenOldH2Database_whenCallgetSchemaMethod_thenThrowAbstractMethodError () gooit SQLException {Connection conn = DriverManager.getConnection (url, gebruikersnaam, ""); assertNotNull (conn); Assertions.assertThrows (AbstractMethodError.class, () -> conn.getSchema ()); }} 

Als we de test uitvoeren, zal deze slagen en bevestigen dat de oproep naar getSchema () gooit AbstracteMethodeFout.

5. Conclusie

Soms kunnen we zien AbstracteMethodeFout tijdens runtime. In dit artikel hebben we aan de hand van voorbeelden besproken wanneer de fout optreedt.

Wanneer we een bibliotheek van onze applicatie upgraden, is het altijd een goede gewoonte om te controleren of andere afhankelijkheden de bibliotheek gebruiken en te overwegen om de gerelateerde afhankelijkheden bij te werken.

Aan de andere kant, zodra we geconfronteerd worden AbstracteMethodeFout, met een goed begrip van deze fout, kunnen we het probleem mogelijk snel oplossen.

Zoals altijd is de volledige broncode van het artikel beschikbaar op GitHub.