Is Instanceof Considered Bad Practice? If So, Under What Circumstances Is Instanceof Still Preferable

Is instanceof considered bad practice? If so, under what circumstances is instanceof still preferable?

I can imagine some cases, for example you have some objects of a library, which you can't extend (or it would be inconvenient to do so), perhaps mixed with some objects of your, all with same base class, together in a collection.

I suppose that in such case, using instanceof to distinguish some processing on these objects might be useful.

Idem in some maintenance of legacy code where you cannot inject some new behavior in lot of old classes just to add a new little feature or some bug fix...

Is it good practice to often use instanceof?

Let's say I am writing some inventory code:

public void showInventory(List<Item> items) {
for (Item item : items) {
if (item instanceof ContainerItem) {
// container display logic here
}
else if (item instanceof WeaponItem) {
// weapon display logic here
}
// etc etc
}
}

That will compile and work just fine. But it misses out on a key idea of object oriented design: You can define parent classes to do general useful things, and have child classes fill in specific, important details.

Alternate approach to above:

abstract class Item {
// insert methods that act exactly the same for all items here

// now define one that subclasses must fill in themselves
public abstract void show()
}
class ContainerItem extends Item {
@Override public void show() {
// container display logic here instead
}
}
class WeaponItem extends Item {
@Override public void show() {
// weapon display logic here instead
}
}

Now we have one place to look, the show() method, in all our child classes for inventory display logic. How do we access it? Easy!

public void showInventory(List<Item> items) {
for (Item item : items) {
item.show();
}
}

We are keeping all the item-specific logic inside specific Item subclasses. This makes your codebase easier to maintain and extend. It reduces the cognitive strain of the long for-each loop in the first code sample. And it readies show() to be reusable in places you haven't even designed yet.

instanceof considered harmful?

Yes, you are on the right track. While instanceof certainly has its uses, heavy use generally indicates that your class design is deficient.

When should and shouldn't instanceof be used?

I find a need to use instanceof hints at bad design. It's a sure sign that a big, complex switch-style construct will follow. Most other times I see it used, we should use polymorphism rather than instanceof. See the Strategy pattern. (relevant examples of use)

The only time I find I need to use it is when implementing equals(Object o).

The performance impact of using instanceof in Java

Modern JVM/JIT compilers have removed the performance hit of most of the traditionally "slow" operations, including instanceof, exception handling, reflection, etc.

As Donald Knuth wrote, "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." The performance of instanceof probably won't be an issue, so don't waste your time coming up with exotic workarounds until you're sure that's the problem.

Is it bad to have If-instanceof-statements in Typescript?

Use the approach of duck typing to avoid conditional scenarios. Source

Have a method called selection() inside each type instance Action1 and Action2 so- on and use that to define the body/desired functionality you want to build. And simply call selection() method avoiding condition. So based on the instance of the type it will call the correct selection() method of the corresponding type

instanceof keyword usage

Generally speaking yes. It's best to keep all code that depends on being a specific class within that class, and using instanceof generally means that you've put some code outside that class.

Look at this very simple example:

public class Animal
{
}

public class Dog extends Animal
{
}

public class Cat extends Animal
{
}

public class SomeOtherClass
{
public abstract String speak(Animal a)
{
String word = "";

if (a instanceof Dog)
{
word = "woof";
}
else if (a instanceof Cat)
{
word = "miaow";
}

return word;
}
}

Ideally, we'd like all of the behaviour that's specific to dogs to be contained in the Dog class, rather than spread around our program. We can change that by rewriting our program like this:

public abstract class Animal
{
public String speak();
}

public class Dog extends Animal
{
public String speak()
{
return "woof";
}
}

public class Cat extends Animal
{
public String speak()
{
return "miaow";
}
}

public class SomeOtherClass
{
public String speak(Animal a)
{
return a.speak();
}
}

We've specified that an Animal has to have a speak method. Now SomeOtherClass doesn't need to know the particular details of each type of animal - it can hand that off to the subclass of Animal.



Related Topics



Leave a reply



Submit