0

I have a type hierarchy where classes B and C inherit abstract class A.

I have a code block like this:

if (someVar instanceof B) {
  return "b";
} else if(someVar instanceof C) {
  return "c";
} else {
  throw new Exception("Missing type handling…");
}

I would like to know if there is an appropriate exception for this in Java, like IllegalArgumentException.

thchp
  • 2,013
  • 1
  • 18
  • 33

2 Answers2

4

IllegalArgumentException is fine.

IllegalArgumentException extends RuntimeException

Thrown to indicate that a method has been passed an illegal or inappropriate argument.

lkatiforis
  • 5,703
  • 2
  • 16
  • 35
  • 3
    Additionally, a useful message is a good idea: `throw new IllegalArgumentException("Unexpected argument of type " + (someVar == null ? "null" : someVar.getClass().getName()))` – VGR Oct 19 '21 at 11:39
  • @VGR i was indeed thinking about adding this kind of info – thchp Oct 19 '21 at 11:41
  • @thchp there is also UnsupportedOperationException which fits the need. However these two exceptions are both runtime exceptions, meaning that you are not forced to try-catch by the compiler. Instead, I would make my own exception extending Exception which will force the caller to implement a fallback for when the type passed along is not the correct one. – Matteo NNZ Oct 19 '21 at 11:42
  • @MatteoNNZ my primary goal is to detect that I forgot to add a new else if statement when I add new types during the development process, so I guess runtime exception is ok – thchp Oct 19 '21 at 11:44
  • 1
    @thchp then why aren't all the classes (B, C etc.) implementing the same interface which returns a String getSomething() so you won't have to worry about enriching the method any longer? – Matteo NNZ Oct 19 '21 at 11:51
  • This is another question I was about to write on SO: i follow domain driven design, so my domain classes cannot depend on the infrastructure. And I need to create entities depending on whether `someVar` is B or C (those are my domain objects I need to map to entities). But if B and C implement the method, I have to add a dependency to the infrastructure to instantiate the entities. – thchp Oct 19 '21 at 11:57
2

Sticking to the question you asked, IllegalArgumentException is a good exception.

However it doesn't look like you're using class hierarchy correctly. If both B and C extend A which is abstract, then I think that the class A should have an abstract method returning whatever you're checking in your if block chain:

public abstract class A {
    public abstract String getHandling(); //<-- or whatever the correct name is
}

So that B and C can say this:

public final class B extends A {
    @Override
    public String getHandling() {
        return "b";
    }
}

public final class C extends A {
    @Override
    public String getHandling() {
        return "c";
    }
}

Then, your function that you show partially above would just declare someVar being of type A:

public void yourFunction(A someVar) {
    return someVar.getHandling();
}

Like that, you never have to worry about implementing the new if each time that someone extend A again.

Either your new class extends A (and in that case it is obliged to provide the handling implementation), or simply the compiler won't accept the object in parameter for you.

Matteo NNZ
  • 11,930
  • 12
  • 52
  • 89
  • This is another question I was about to write on SO: i follow domain driven design, so my domain classes cannot depend on the infrastructure. And I need to create entities depending on whether someVar is B or C (those are my domain objects I need to map to entities). But if B and C implement the method, I have to add a dependency to the infrastructure to instantiate the entities. – thchp Oct 19 '21 at 11:58