Statische en dynamische binding in Java

1. Inleiding

Met polymorfisme kan een object meerdere vormen aannemen - wanneer een methode polymorfisme vertoont, moet de compiler de naam van de methode toewijzen aan de uiteindelijke implementatie.

Als het tijdens het compileren in kaart is gebracht, is het een statische of vroege binding.

Als het tijdens runtime wordt opgelost, staat het bekend als dynamische of late binding.

2. Begrijpen door middel van een code

Wanneer een subklasse een superklasse uitbreidt, kan deze de daarin gedefinieerde methoden opnieuw implementeren. Dit wordt een methode-overschrijving genoemd.

Laten we bijvoorbeeld een superklasse maken Dier:

openbare klasse Animal {statische Logger-logger = LoggerFactory.getLogger (Animal.class); public void makeNoise () {logger.info ("generiek dierlijk geluid"); } public void makeNoise (Integer herhalingen) {while (herhalingen! = 0) {logger.info ("generiek aftellen van dierlijk geluid" + herhalingen); herhalingen - = 1; }}}

En een subklasse Hond:

openbare klasse Hond breidt uit Dier {statische Logger-logger = LoggerFactory.getLogger (Dog.class); @Override public void makeNoise () {logger.info ("woof woof!"); }}

Over het overbelasten van een methode, zoals de herrie maken() van Dier class, zal de compiler de methode en zijn code tijdens het compileren oplossen. Dit is een voorbeeld van statische binding.

Als we echter een object van het type Hond naar een verwijzing van het type Dier, zal de compiler de functiecodetoewijzing tijdens runtime oplossen. Dit is een dynamische binding.

Laten we, om te begrijpen hoe dit werkt, een klein codefragment schrijven om de klassen en de bijbehorende methoden aan te roepen:

Dierlijk dier = nieuw dier (); // methoden van dierlijk object aanroepen animal.makeNoise (); animal.makeNoise (3); // een hondenobject toewijzen aan een referentie van het type Animal Animal dogAnimal = new Dog (); dogAnimal.makeNoise (); De output van de bovenstaande code zal zijn:
com.baeldung.binding.Animal - generiek dierlijk geluid com.baeldung.binding.Animal - generiek dierlijk geluid aftellen 3 com.baeldung.binding.Animal - algemeen dierlijk geluid aftellen 2 com.baeldung.binding.Animal - algemeen dierlijk geluid aftellen 1 com.baeldung.binding.Dog - inslag inslag!

Laten we nu een klas maken:

class AnimalActivity {public static void eat (Animal animal) {System.out.println ("Animal is aan het eten"); } public static void eat (Dog dog) {System.out.println ("Dog is aan het eten"); }}

Laten we deze de regel toevoegen aan de hoofdklasse:

AnimalActivity.eat (dogAnimal);

De output zou zijn:

com.baeldung.binding.AnimalActivity - Dier is aan het eten

Dit voorbeeld laat zien dat een statische functie een statische binding ondergaat.

De reden is dat subklassen statische methoden niet kunnen overschrijven. Als de subklasse dezelfde methode zou implementeren, zou het de methode van de superklasse verbergen. Evenzo, als een methode definitief of privé is, zal de JVM een statische binding uitvoeren.

Een statisch gebonden methode is niet geassocieerd met een bepaald object, maar wordt eerder aangeroepen Type (klasse in Java). De uitvoering van een dergelijke methode is iets sneller.

Elke andere methode is standaard automatisch een virtuele methode in Java. De JVM lost dergelijke methoden tijdens runtime op en dit is dynamische binding.

De exacte implementatie hangt af van de JVM, maar er is een C ++ -achtige benadering voor nodig, waarbij de JVM de virtuele tabel opzoekt om te beslissen op welk object de methode wordt aangeroepen.

3. Conclusie

Binding is een integraal onderdeel van een taal die polymorfisme implementeert, het is belangrijk om de implicaties van zowel statische als dynamische binding te begrijpen om er zeker van te zijn dat onze applicaties zich gedragen zoals we dat willen.

Met dat begrip zijn we echter in staat om zowel klasse-overerving als methode-overbelasting effectief te gebruiken.

Zoals altijd is de code beschikbaar op GitHub.