So I have this relevant code…
public class PokemonTrainer {
private Pokemon p = new Squirtle();
private String name;
public PokemonTrainer(String name) {
this.name = name;
}
public static void main(String[] args) {
PokemonTrainer pt = new PokemonTrainer("Ash");
try {pt.fightGary();}
catch (Charmander c) {
System.out.println("You were roasted by a Charmander.");
}
catch (Squirtle s) {
System.out.println("You were drowned by a Squirtle.");
}
catch (Bulbasaur b) {
System.out.println("You were strangled by a Bulbasaur.");
}
catch (Pokemon p) {
System.out.println("You survived!");
}
}
public void fightGary() throws Pokemon {
throw p;
}
public class Pokemon extends Exception {}
public class Bulbasaur extends Pokemon {}
public class Squirtle extends Pokemon {}
public class Charmander extends Pokemon {}
Why is it that this prints “You were drowned by a Squirtle”?
In my reasoning, “catch” is a method, and when an object is passed into a method, the method evaluates based on the object’s STATIC TYPE — that is, “Pokemon”, in this case — this is demonstrated in the below short example:
public class PokemonTrainer {
private Pokemon p = new Squirtle();
private String name;
public PokemonTrainer(String name) {
this.name = name;
}
public static void main(String[] args) {
PokemonTrainer pt = new PokemonTrainer("Ash");
pt.fightGary(pt.p); // ------------ Prints "Pokemon!!!"
}
public void fightGary(Pokemon p) {
System.out.println("Pokemon!!!");
}
public void fightGary(Squirtle s) {
System.out.println("Squirtle!!!");
}
}
So what’s different about these two examples? Why does the first example print what it does?
Thanks!
That’s the first mistake.
catchisn’t a method, and trying to think of it as if it were is going to cause you problems.It’s a language construct with its own rules. You should read the language specification section 14.20 or the exceptions tutorial for more information.
In short, when you have a sequence of
catchblocks, the first one which matches the execution time type of the thrown exception is executed. (The compiler will prevent you from catching a more-general exception before a more-specific one.)So if you have:
then if
doSomething()throws aFileNotFoundExceptionit will execute the firstcatchblock (and only that one) – whereas if it throws any other kinds ofIOException, it will execute the secondcatchblock. Any other exceptions will propagate up the stack.