Wanneer gebruik je de annotatie van Java’s @Override en waarom?

Wat zijn de beste praktijken voor het gebruik van Java’s @Overrideannotatie en waarom?

Het lijkt erop dat het overkill zou zijn om elke afzonderlijke opheffingsmethode te markeren met de @Overrideannotatie. Zijn er bepaalde programmeersituaties die bellen voor het gebruik van de @Overrideen anderen die nooit de @Overridemogen gebruiken?


Antwoord 1, Autoriteit 100%

Gebruik het elke keer dat u een methode voor twee voordelen overschrijdt. Doe het, zodat u kunt profiteren van de compilercontrole om ervoor te zorgen dat u eigenlijk een methode overschrijft wanneer u denkt dat u bent. Op deze manier, als u een gemeenschappelijke fout maakt om een ​​methode-naam te missen of niet correct aan te passen aan de parameters, wordt u gewaarschuwd dat u methode niet echt overschrijdt terwijl u denkt. Ten tweede maakt het uw code gemakkelijker te begrijpen omdat het duidelijker is wanneer methoden worden overschreven.

Bovendien kunt u het in Java 1.6 gebruiken om te markeren wanneer een methode een interface implementeert voor dezelfde voordelen. Ik denk dat het beter zou zijn om een ​​aparte annotatie te hebben (zoals @Implements), maar het is beter dan niets.


Antwoord 2, Autoriteit 21%

Ik denk dat het het meest bruikbaar is als een compilertijdherinnering dat de intentie van de methode is om een ​​bovenliggende methode te negeren. Als een voorbeeld:

protected boolean displaySensitiveInformation() {
  return false;
}

Je ziet vaak iets als de bovenstaande methode die een methode in de basisklasse overschrijdt. Dit is een belangrijk implementatiedetail van deze klasse – we willen geen gevoelige informatie die moet worden weergegeven.

Stel dat deze methode wordt gewijzigd in de ouderklasse naar

protected boolean displaySensitiveInformation(Context context) {
  return true;
}

Deze wijziging veroorzaakt geen fouten tijdens het compileren of waarschuwingen, maar verandert het beoogde gedrag van de subklasse volledig.

Om je vraag te beantwoorden: je moet de @Override-annotatie gebruiken als het ontbreken van een methode met dezelfde handtekening in een superklasse wijst op een bug.


Antwoord 3, autoriteit 9%

Er zijn hier veel goede antwoorden, dus laat me een andere manier bieden om ernaar te kijken…

Er is geen overkill bij het coderen. Het kost je niets om @override te typen, maar de besparingen kunnen enorm zijn als je een methodenaam verkeerd hebt gespeld of de handtekening een beetje verkeerd hebt gebruikt.

Denk er zo over na: in de tijd dat je hier navigeerde en dit bericht typte, heb je vrijwel meer tijd gebruikt dan je voor de rest van je leven aan @override zult besteden; maar één fout die het voorkomt, kan u uren besparen.

Java doet er alles aan om ervoor te zorgen dat je tijdens het bewerken/compileren geen fouten hebt gemaakt. Dit is een vrijwel gratis manier om een hele reeks fouten op te lossen die op geen enkele andere manier te voorkomen zijn dan uitgebreid testen .

Kunt u een beter mechanisme in Java bedenken om ervoor te zorgen dat wanneer de gebruiker van plan was een methode te negeren, hij dit ook daadwerkelijk deed?

Een ander leuk effect is dat als je de annotatie niet opgeeft, het je tijdens het compileren waarschuwt dat je per ongeluk een bovenliggende methode hebt overschreven – iets dat significant zou kunnen zijn als je niet van plan was het te doen.

>


Antwoord 4, autoriteit 4%

Ik gebruik altijd de tag. Het is een eenvoudige compileervlag om kleine fouten op te sporen die ik zou kunnen maken.

Het vangt dingen op als toString()in plaats van toString()

De kleine dingen helpen bij grote projecten.


Antwoord 5, Autoriteit 3%

Gebruik van de @Overrideannotatie fungeert als een compileer-tijdsbeveiliging tegen een gemeenschappelijke programmeerfout. Het geeft een compilatiefout als u de annotatie hebt op een methode die u niet daadwerkelijk de superclass-methode overschrijft.

Het meest voorkomende geval waarin dit nuttig is, is wanneer u een methode in de basisklasse verandert om een ​​andere parameterlijst te hebben. Een methode in een subklasse die werd gebruikt om de SUPERCLASS-methode te negeren, zal dit niet langer doen vanwege de gewijzigde handtekening van de methode. Dit kan soms vreemd en onverwacht gedrag veroorzaken, vooral bij het omgaan met complexe overervingstructuren. De @Overrideannotatie-waarborgen tegen dit.


Antwoord 6, Autoriteit 3%

Om te profiteren van de compilercontrole, moet u altijd de annotatie van de negeren gebruiken. Maar vergeet niet dat Java Compiler 1.5 deze annotatie niet toestaat bij het overschrijven van interfacemethoden. U kunt het gewoon gebruiken om klassenmethoden (abstract of niet) te negeren.

Sommige ides, als Eclipse, zelfs geconfigureerd met Java 1.6 runtime of hoger, behouden ze de naleving van Java 1.5 en laten het gebruik @Override niet toe zoals hierboven beschreven. Om dat gedrag te voorkomen, moet u naar: projecteigenschappen – & GT; Java Compiler – & GT; Controleer “Inschakelen projectspecifieke instellingen” – & GT; Kies “Compiler Compliance Level” = 6.0 of hoger.

Ik hou ervan om deze annotatie elke keer te gebruiken. Elke keer dat ik een methode onafhankelijk doormaak, als de basis een interface is, of klasse.

Hiermee kunt u een aantal typische fouten vermijden, zoals wanneer u denkt dat u een gebeurtenishandler overschrijdt en dan ziet u er niets gebeurt. Stel je voor dat je een gebeurtenisluisteraar wilt toevoegen aan een UI-component:

someUIComponent.addMouseListener(new MouseAdapter(){
  public void mouseEntered() {
     ...do something...
  }
});

De bovenstaande code wordt gecompileerd en uitgevoerd, maar als u de muis binnen een UIComponent beweegt, wordt de code “doe iets” uitgevoerd, omdat u in feite de basismethode mouseEntered(MouseEvent ev)niet overschrijft. U maakt gewoon een nieuwe parameterloze methode mouseEntered(). Als je in plaats van die code de annotatie @Overridehebt gebruikt, heb je een compileerfout gezien en heb je geen tijd verspild aan het bedenken waarom je gebeurtenishandler niet actief was.


Antwoord 7, autoriteit 2%

@Override op interface-implementatieis inconsistent omdat er niet zoiets bestaat als “een interface overschrijven” in java.

@Override op interface-implementatieis nutteloos omdat het in de praktijk geen bugs opvangt die de compilatie toch niet zou opvangen.
Er is maar één, vergezocht scenario waarin het overschrijven van implementeerders daadwerkelijk iets doet: als je een interface implementeert, en de interface REMOVES-methoden, krijg je bij het compileren een melding dat je de ongebruikte implementaties moet verwijderen. Merk op dat als de nieuwe versie van de interface NIEUWE of GEWIJZIGDE methoden heeft, je natuurlijk sowieso een compileerfout krijgt omdat je de nieuwe dingen niet implementeert.

@Override op interface-implementers had nooit toegestaan moeten zijn in 1.6, en met eclipse die er helaas voor kiest om de annotaties automatisch in te voegen als standaardgedrag, krijgen we veel rommelige bronbestanden. Als je 1.6-code leest, kun je aan de @Override-annotatie niet zien of een methode een methode in de superklasse overschrijft of alleen een interface implementeert.

Het gebruik van @Override bij het overschrijven van een methode in een superklasse is prima.


Antwoord 8, autoriteit 2%

Het is het beste om het te gebruiken voor elke methode die bedoeld is als een overschrijving, en Java 6+, voor elke methode die bedoeld is als een implementatie van een interface.

Ten eerste detecteert het spelfouten zoals “hashCode()” in plaats van “hashCode()” tijdens het compileren. Het kan verbijsterend zijn om te debuggen waarom het resultaat van uw methode niet overeenkomt met uw code, terwijl de echte oorzaak is dat uw code nooit wordt aangeroepen.

Als een superklasse de handtekening van een methode wijzigt, kunnen overschrijvingen van de oudere handtekening worden “verweesd”, achtergelaten als verwarrende dode code. Met de annotatie @Overridekunt u deze weeskinderen identificeren, zodat ze kunnen worden aangepast aan de nieuwe handtekening.


Antwoord 9

Als je merkt dat je vaak (niet-abstracte) methoden overschrijft, wil je waarschijnlijk je ontwerp eens bekijken. Het is erg handig wanneer de compiler de fout anders niet zou opvangen. Probeer bijvoorbeeld initValue() in ThreadLocal te overschrijven, wat ik heb gedaan.

Het gebruik van @Override bij het implementeren van interfacemethoden (1.6+ functie) lijkt me een beetje overdreven. Als je heel veel methoden hebt waarvan sommige overschrijven en andere niet, is dat waarschijnlijk weer een slecht ontwerp (en je editor zal waarschijnlijk laten zien welke welke is als je het niet weet).


Antwoord 10

@Override op interfaces is eigenlijk handig, omdat je waarschuwingen krijgt als je de interface verandert.


Antwoord 11

Een ander ding dat het doet, is dat het bij het lezen van de code duidelijker wordt dat het het gedrag van de bovenliggende klasse verandert. Dan kan helpen bij het debuggen.

Ook in Joshua Block’s boek Effective Java (2e editie), geeft item 36 meer details over de voordelen van de annotatie.


Antwoord 12

Het heeft absoluut geen zin om @Override te gebruiken bij het implementeren van een interfacemethode. In dat geval heeft het geen voordeel om het te gebruiken – de compiler zal je fout al opvangen, dus het is gewoon onnodige rommel.


Antwoord 13

Telkens wanneer een methode een andere methode overschrijft, of een methode een handtekening in een interface implementeert.

De @Overrideannotatie verzekert je dat je in feite iets hebt overschreven. Zonder de annotatie riskeert u een spelfout of een verschil in parametertypes en nummer.


Antwoord 14

Ik gebruik het elke keer. Het is meer informatie die ik kan gebruiken om snel te achterhalen wat er aan de hand is als ik de code over een jaar opnieuw bekijk en ik ben vergeten wat ik de eerste keer dacht.


Antwoord 15

Het beste is om het altijd te gebruiken (of laat de IDE ze voor je vullen)

Het nut van @Override is om veranderingen in bovenliggende klassen te detecteren die niet in de hiërarchie zijn gerapporteerd.
Zonder dit kunt u de handtekening van een methode wijzigen en vergeten de overschrijvingen te wijzigen, met @Override zal de compiler het voor u opvangen.

Zo’n vangnet is altijd handig om te hebben.


Antwoord 16

Ik gebruik het overal.
Wat betreft de inspanning voor het markeren van methoden, ik laat Eclipse het voor mij doen, dus het is geen extra inspanning.

Ik ben religieus over continue refactoring… dus ik zal alles gebruiken om het soepeler te laten verlopen.


Antwoord 17

  • Alleen gebruikt voor methodedeclaraties.
  • Geeft aan dat de geannoteerde methode
    aangifte overschrijft een aangifte
    in supertype.

Als het consequent wordt gebruikt, beschermt het je tegen een groot aantal snode bugs.

Gebruik @Override-annotatie om deze bugs te voorkomen:
(Zoek de fout in de volgende code:)

public class Bigram {
    private final char first;
    private final char second;
    public Bigram(char first, char second) {
        this.first  = first;
        this.second = second;
    }
    public boolean equals(Bigram b) {
        return b.first == first && b.second == second;
    }
    public int hashCode() {
        return 31 * first + second;
    }
    public static void main(String[] args) {
        Set<Bigram> s = new HashSet<Bigram>();
        for (int i = 0; i < 10; i++)
            for (char ch = 'a'; ch <= 'z'; ch++)
                s.add(new Bigram(ch, ch));
        System.out.println(s.size());
    }
}

bron: Effectieve Java


Antwoord 18

Wees voorzichtig wanneer u Override gebruikt, omdat u achteraf geen reverse-engineering in starUML kunt uitvoeren; maak eerst de uml.


Antwoord 19

Het lijkt erop dat de wijsheid hier aan het veranderen is. Vandaag heb ik IntelliJ IDEA9 geïnstalleerd en merkte dat het “missing @Override inspection” vangt nu niet alleen geïmplementeerde abstracte methoden op, maar ook geïmplementeerde interfacemethoden. In de codebasis van mijn werkgever en in mijn eigen projecten heb ik lang de gewoonte gehad om @Override alleen te gebruiken voor de eerstgenoemde – geïmplementeerde abstracte methoden. Als we echter de gewoonte heroverwegen, wordt de verdienste van het gebruik van de annotaties in beide gevallen duidelijk. Ondanks dat het uitgebreider is, beschermt het tegen het fragiele basisklasse-probleem (niet zo ernstig als C++-gerelateerde voorbeelden) waarbij de naam van de interfacemethode verandert, waardoor de toekomstige implementatiemethode verweesd wordt in een afgeleide klasse.

Natuurlijk is dit scenario meestal hyperbool; de afgeleide klasse zou niet langer compileren, nu een implementatie van de hernoemde interfacemethode ontbreekt, en vandaag zou men waarschijnlijk een refactoring-operatie Rename Methodgebruiken om de hele codebasis massaal aan te pakken.

Aangezien IDEA’s inspectie niet kan worden geconfigureerd om geïmplementeerde interfacemethoden te negeren, zal ik vandaag zowel mijn gewoonte als de criteria voor codebeoordeling van mijn team veranderen.


Antwoord 20

De annotatie @Override wordt gebruikt om te helpen controleren of de ontwikkelaar de juiste methode in de bovenliggende klasse of interface moet overschrijven. Wanneer de naam van super’s methoden verandert, kan de compiler dat geval melden, wat alleen is om de consistentie met de super en de subklasse te behouden.

BTW, als we de annotatie @Override in de subklasse niet hebben aangekondigd, maar we wel enkele methoden van de super overschrijven, dan kan de functie werken zoals die met de @Override. Maar deze methode kan de ontwikkelaar niet op de hoogte stellen wanneer de methode van de super is gewijzigd. Omdat het het doel van de ontwikkelaar niet kende – de methode van super overschrijven of een nieuwe methode definiëren?

Dus als we die methode willen overschrijven om gebruik te maken van het polymorfisme, kunnen we beter @Override toevoegen boven de methode.


Antwoord 21

Ik gebruik het zo veel als ik kan om te identificeren wanneer een methode wordt overschreven. Als je naar de programmeertaal Scala kijkt, hebben ze ook een override-trefwoord. Ik vind het handig.


Antwoord 22

Het stelt u (nou ja, de compiler) in staat om op te merken wanneer u de verkeerde spelling hebt gebruikt voor een methodenaam die u overschrijft.


Antwoord 23

Annotatie overschrijven wordt gebruikt om voordeel te halen uit de compiler, om te controleren of u daadwerkelijk een methode uit de bovenliggende klasse overschrijft. Het wordt gebruikt om u op de hoogte te stellen als u een fout maakt, zoals een fout bij het verkeerd spellen van een methodenaam, een fout bij het niet correct overeenkomen van de parameters


Antwoord 24

Ik denk dat het het beste is om de @override te coderen wanneer dit is toegestaan. het helpt bij het coderen. er moet echter worden opgemerkt dat voor ecipse Helios, ofwel sdk 5 of 6, de @override-annotatie voor geïmplementeerde interfacemethoden is toegestaan. wat betreft Galileo, 5 of 6, @override annotatie is niet toegestaan.


Antwoord 25

Annotaties leveren metagegevens over de code aan de compiler en de annotatie @Override wordt gebruikt in geval van overerving wanneer we een methode van basisklasse overschrijven. Het vertelt de compiler alleen dat je de methode overschrijft. Het kan een aantal veelvoorkomende fouten voorkomen die we kunnen doen, zoals het niet volgen van de juiste handtekening van de methode of spelfouten in de naam van de methode enz. Het is dus een goede gewoonte om @Override-annotatie te gebruiken.


Antwoord 26

Voor mij zorgt de @Override ervoor dat ik de handtekening van de methode correct heb. Als ik de annotatie invoer en de methode is niet correct gespeld, dan klaagt de compiler en laat me weten dat er iets mis is.


Antwoord 27

Eenvoudig: als u een methode in uw superklasse wilt overschrijven, gebruikt u de annotatie @Overrideom een correcte overschrijving te maken. De compiler zal je waarschuwen als je het niet correct overschrijft.

Other episodes