所以我有这个相关的代码......
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 {}
为什么打印“你被一个Squirtle淹死了”?
在我的推理中,“catch”是一种方法,当一个对象被传递给一个方法时,该方法根据对象的STATIC TYPE进行评估 - 也就是说,“Pokemon”,在这种情况下 - 这被证明在下面的简短例子中:
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!!!");
}
}
那么这两个例子有什么不同?为什么第一个例子打印它的作用?
谢谢!
答案 0 :(得分:8)
在我的推理中,“catch”是一种方法
这是第一个错误。 catch
不是一种方法,并试图将其视为可能会导致问题。
这是一种具有自己规则的语言结构。您应该阅读language specification section 14.20或exceptions tutorial以获取更多信息。
简而言之,当您有一系列catch
块时,将执行第一个匹配抛出异常的执行时间类型的块。 (编译器将阻止您在更具体的异常之前捕获更一般的异常。)
所以如果你有:
try {
doSomething();
} catch (FileNotFoundException e) {
...
} catch (IOException e) {
...
}
然后,如果doSomething()
抛出FileNotFoundException
,它将执行第一个catch
块(而仅那个) - 而如果它抛出任何其他类型的IOException
,它将执行第二个catch
块。任何其他异常都会在堆栈中传播。
答案 1 :(得分:1)
嗯,catch
不是一种方法,而是Java语言的一部分。
但是要回答您的问题,p
是Squirtle
的实例:
Pokemon p = new Squirtle();
由于有一个catch
子句可以捕获Squirtle
,所以它就是这样。
catch (Squirtle s)
如果此行不存在,则更通用
catch (Pokemon p)
会处理抛出的Squirtle
。
答案 2 :(得分:1)
虽然Pokemon p
被声明为口袋妖怪,但它被实例化为带有new Squirtle()
的Squirtle。因为它在内部是一个Squirtle,getClass()
,当它被调用时,将返回Squirtle.class,因此try-catch在甚至检查Pokemon catch之前捕获Squirtle catch。
这称为polymorphism。
关于你的推理,catch
不是一个方法,而是一个带有try
块的语句,用于声明在抛出某些异常的情况下该怎么做。
答案 3 :(得分:1)
您将reference
的类型与object
的类型混淆。
Catch更像是switch
对象上的instanceof
。
考虑一个更简单的例子
String s = "hello";
Object o = s;
在这种情况下,o
的引用类型为Object
,但String
和s
的对象类型为o
,因为它们相同对象