Wordt instanceof beschouwd als een slechte gewoonte? Zo ja, onder welke omstandigheden verdient instanceof nog steeds de voorkeur?

In de loop der jaren heb ik geprobeerd instanceofwaar mogelijk te vermijden. Gebruik waar van toepassing polymorfisme of het bezoekerspatroon. Ik veronderstel dat het in sommige situaties eenvoudig het onderhoud vereenvoudigt… Zijn er nog andere nadelen waar men rekening mee moet houden?

Ik zie het echter hier en daar in de Java-bibliotheken, dus ik neem aan dat het zijn plaats heeft? Onder welke omstandigheden heeft het de voorkeur? Is het ooit onvermijdelijk?


Antwoord 1, autoriteit 100%

Het heeft zeker zijn plaats in een standaardimplementatie van equals. Bijv.

public boolean equals ( Object o )
{
  if ( this == o )
  {
     return true;
  }
  if ( ! (o instanceof MyClass) )
  {
    return false;
  }
  // Compare fields
  ...
}

Een handig ding om te weten over instanceof is dat de LHS nullkan zijn en in dat geval evalueert de expressie naar false.


Antwoord 2, autoriteit 61%

Ik kan me enkele gevallen voorstellen, je hebt bijvoorbeeld enkele objecten van een bibliotheek die je niet kunt uitbreiden (of het zou onhandig zijn om dit te doen), misschien vermengd met enkele objecten van je, allemaal met dezelfde basisklasse, samen in een collectie.
Ik veronderstel dat in zo’n geval het nuttig kan zijn om instanceof te gebruiken om bepaalde verwerkingen op deze objecten te onderscheiden.

Idem voor wat onderhoud van verouderde code waarbij je geen nieuw gedrag in veel oude klassen kunt injecteren alleen om een ​​nieuwe kleine functie of een bugfix toe te voegen…


Antwoord 3, autoriteit 57%

Ik denk dat wanneer je absoluut het type object moet weten, instanceofde beste beschikbare optie is.

Een slechte gewoonte zou zijn om veel instanceofs naast elkaar te hebben en volgens hen verschillende methoden van de objecten aan te roepen (natuurlijk casten).
Dit zou er waarschijnlijk op wijzen dat de hiërarchie opnieuw moet worden bekeken en waarschijnlijk moet worden herzien.


Antwoord 4, autoriteit 26%

Als je in een puur OO-model zit, dan is instanceofzeker een codegeur.

Als u echter geen 100% OO-model gebruikt of als u er dingen van buitenaf in moet injecteren, gebruik dan instanceof of equivalenten (isXXX(), getType(), …) kan zijn nut hebben.

De algemene “regel” zou zijn om deze waar mogelijk te vermijden, vooral wanneer ude typehiërarchie beheert en bijvoorbeeld subtypepolymorfisme kunt gebruiken. Het idee is niet om het object te vragen wat voor type het is en er iets mee te doen, maar om het object direct of indirect via een Bezoeker (in wezen dubbel polymorfisme) te vragen om een ​​handeling uit te voeren.


Antwoord 5, autoriteit 9%

Het kan goed worden gebruikt als een gezond verstandscontrole voor het casten; naast het controleren of uw object van het juiste type is, controleert het ook of het niet null is.

if (o instanceof MyThing) {
    ((MyThing) o).doSomething(); // This is now guaranteed to work.
} else {
    // Do something else, but don't crash onto ClassCast- or NullPointerException.
}

Antwoord 6, autoriteit 9%

Ik ben het ermee eens dat het een slechte geur kan hebben. Veel gevallen, vooral in een aan elkaar geketend blok, stinkt naar slechte dingen.

Soms kan het zich gedragen op manieren die je niet zou verwachten… Iets wat ik een keer heb meegemaakt:

Class B extends A
Class C extends A
B b = new B();
C c = new C();
b instanceof B -> true
b instanceof C -> true
c instanceof C -> true
c instanceof B -> true

(in mijn geval gebeurde dit vanwege het maken van proxy-objecten in de slaapstand…. maar alleen in een geval waarbij code die afhankelijk is van instanceof riskant is)


Antwoord 7

Hoe zit het in het geval van een creatiefabriek?
bijv.

public static Cage createCage(Animal animal) {
  if (animal instanceof Dog)
    return new DogHouse();
  else if (animal instanceof Lion)
    return new SteelCage();
  else if (animal instanceof Chicken)
    return new ChickenWiredCage();
  else if (animal instanceof AlienPreditor)
    return new ForceFieldCage();
  ...
  else
    return new GenericCage();
}

Other episodes