我对以下代码感到困惑:
class MyException extends Exception {}
class AnotherException extends MyException {}
class Foo {
public function something() {
print "throwing AnotherException\n";
throw new AnotherException();
}
public function somethingElse() {
print "throwing MyException\n";
throw new MyException();
}
}
$a = new Foo();
try {
try {
$a->something();
} catch(AnotherException $e) {
print "caught AnotherException\n";
$a->somethingElse();
} catch(MyException $e) {
print "caught MyException\n";
}
} catch(Exception $e) {
print "caught Exception\n";
}
我希望这能输出:
throwing AnotherException
caught AnotherException
throwing MyException
caught MyException
但它输出:
throwing AnotherException
caught AnotherException
throwing MyException
caught Exception
有人可以解释为什么它“跳过”捕获(MyException $ e)?
感谢。
答案 0 :(得分:16)
异常处理程序捕获由try块范围内的代码引发的异常。
对$a->somethingElse()
的调用不会发生在与跳过的异常处理程序关联的try块中。它发生在另一个catch子句中。
仅仅因为它看起来在物理上低于引发异常的行,不足以覆盖该代码。
缩进括号的样式选择使这不太清楚,恕我直言。前一个try块的close括号出现在与下一个catch相同的行上,即使它们是不相关的(好的,同级的)作用域。
答案 1 :(得分:6)
只是因为评论中没有足够的空间。想想try ... catch作为if ... else循环。您不会期望以下内容:
$a = 10;
if($a == 9)
print "\$a == 9";
elseif($a == 10) {
$a = 11;
echo "now \$a == 11";
} elseif($a == 11) {
echo "\$a == 11";
}
打印出最后一个条件(“\ $ a == 11”),因为第一个elseif
已满足条件。 try ... catch也是如此。如果满足条件,则不会继续在同一范围内搜索新条件。
答案 2 :(得分:1)
我不确定以下是否合法("尝试在catch区块内),但确实给出了预期的输出:
class MyException extends Exception {}
class AnotherException extends MyException {}
class Foo {
public function something() {
print "throwing AnotherException\n";
throw new AnotherException();
}
public function somethingElse() {
print "throwing MyException\n";
throw new MyException();
}
}
$a = new Foo();
try {
try {
$a->something();
} catch(AnotherException $e) {
print "caught AnotherException\n";
try{
$a->somethingElse();
} catch(MyException $e) {
print "caught MyException\n";
}
}
} catch(Exception $e) {
print "caught Exception\n";
}
提供输出:
throwing AnotherException
caught AnotherException
throwing MyException
caught MyException
答案 3 :(得分:0)
不确定这是否被认为是回答,但答案甚至比这里提出的更简单。对于每次尝试,只能触发一个捕获块,它始终是最具体的一个。
在这种情况下,AnotherException由内部try / catch的第一个catch块抛出并处理,因此第二个catch块不会处理它。 catch块中抛出的新异常由外部try / catch处理。