### java异常处理语法结构 ###
try
{
// 业务实现代码
}
catch
{
// 异常处理块1
}
catch
{
// 异常处理块2
}
finally
{
// 资源回收快
}
### 异常概述 ###
异常机制可以使程序中的异常处理代码和正常业务代码分离。
先处理小异常,再处理大异常。
异常能处理就早处理,抛出不去还不能处理的就想法消化掉或者转换为RuntimeException处理。
可以把错误集中起来,一次处理所有的错误。
五个关键字try,catch,finally,throw,throws
其中try...catch用来捕捉异常。
抛出大量异常是有问题的,应该从程序开发角度尽可能的控制异常发生的可能。
不要使用过于庞大的try块,造成后面紧跟大量的catch,导致分析异常原因的难度大大增加。
尽量避免在实际应用中捕捉Throwable。
不要忽略捕捉到的异常,catch为空或仅仅打印出错信息都是不妥的,要处理异常或重新抛出异常。
### 作用以及限制 ###
作用:
①what
如果异常机制使用恰当,被抛出异常的类型可以表明发生了什么程序错误。
②where
发生异常之后,而Stack Trace可以清楚的告诉我们什么地方发生了错误。
③why
为什么发生错误则可以通过看异常信息和Stack Trace来分析。
如果你的异常不能解决上面的3W问题,那么可以证明你对异常使用一定不正确。
限制:
1 把异常和普通错误混在一起。
2 使用异常处理代替流程控制。
其实,对于普通的错误,应该编写处理这种错误的代码,增加程序的健壮性,只用对外部的、不能确定和预知的运行时错误才使用异常。不要使用一场来代替正常的业务逻辑判断。
### try块里声明的变量只能在try块里有效,在catch块里不可以使用
### 分类 ###
1 Error与Exception
Error:称为错误,由Java虚拟机生成并抛出,包括动态链接失败、虚拟机错误等,程序对其不做处理,也可以说成不可以处理的异常。
Exception:所有异常类的父类,其子类对应了各种各种具体可能出现的异常事件,一般需要用户声明或捕获,也叫可处理的异常。
2 runtimeException与非运行时异常(其他异常)
runtimeException:一类特殊的异常,如被0除、数组下界超范围,其产生比较频繁,处理麻烦,如果声明或捕获将会对程序可读性和运行效率影响很大。因此系统自动检测并将它们交给缺省的异常处理程序,这样的异常可以处理也可以不处理。
非运行时异常:是RuntimeException以外的异常,类型上都属于Exception类及其子类,这类异常是必须要处理的异常,否则程序就不能编译通过。
### 可同时捕获多个异常 ###
捕获多异常,异常类型用 | 分开;
捕获多异常时,异常变量有隐形的final修饰,因此程序不能对异常变量重新赋值。
### 访问异常信息的方法 ###
printStackTrace():将跟踪栈信息输出到标准错误输出。
虽然printStackTrace可以很方便的追踪异常的发生情况,可以用来调试程序,但在最后发布的程序中,应该避免使用它,而应该对捕获的一场进行适当的处理。
getStackTrace():返回该异常的跟踪栈信息。
### finally ###
回收try块中打开的一些物理资源(数据库连接,网络连接,和磁盘连接等)。
java的垃圾回收机制不会回收任何物理资源,只能回收堆内存中对象所占用的内存。
除非在try块或catch块里调用了退出JVM的System.exit(),否则异常处理的finally块总会执行。
通常情况下不要再finally块中使用return或throw语句,否则会导致try、catch里的throw、return语句失效。
### 自动关闭资源的try语句 ###
### throws ###
如果某段代码调用了一个带有throws声明的方法,抛出checked异常,则表明该方法希望他的调用者来处理该异常。
否则将异常交给JVM处理,打印异常的跟踪栈信息,并终止程序运行。
子类抛出的异常不允许比父类多。
### throw 及自定义异常类###
自行抛出异常时,抛出RuntimeException更好,更灵活
throw new Exception
程序:
```
public class ThrowTest
{
public static void main(String[] args)
{
try
{
// 调用声明抛出Checked异常的方法,要么显式捕获该异常
// 要么在main方法中再次声明抛出
throwChecked(-3);
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
// 调用声明抛出Runtime异常的方法既可以显式捕获该异常,
// 也可不理会该异常
throwRuntime(3);
}
public static void throwChecked(int a)throws Exception
{
if (a > 0)
{
//自行抛出Exception异常
//该代码必须处于try块里,或处于带throws声明的方法中
throw new Exception("a的值大于0,不符合要求");
}
}
public static void throwRuntime(int a)
{
if (a > 0)
{
//自行抛出RuntimeException异常,既可以显式捕获该异常
//也可完全不理会该异常,把该异常交给该方法调用者处理
throw new RuntimeException("a的值大于0,不符合要求");
}
}
}
很少抛出自定义异常类
### catch和throw同时使用 ###
public class AuctionTest
{
private double initPrice = 30.0;
// 因为该方法中显式抛出了AuctionException异常,
// 所以此处需要声明抛出AuctionException异常
public void bid(String bidPrice)
throws AuctionException
{
double d = 0.0;
try
{
d = Double.parseDouble(bidPrice);
}
catch (Exception e)
{
// 此处完成本方法中可以对异常执行的修复处理,
// 此处仅仅是在控制台打印异常跟踪栈信息。
e.printStackTrace();
//再次抛出自定义异常
throw new AuctionException("竞拍价必须是数值,"
+ "不能包含其他字符!");
}
if (initPrice > d)
{
throw new AuctionException("竞拍价比起拍价低,"
+ "不允许竞拍!");
}
initPrice = d;
}
public static void main(String[] args)
{
AuctionTest at = new AuctionTest();
try
{
at.bid("df");
}
catch (AuctionException ae)
{
// 再次捕捉到bid方法中的异常。并对该异常进行处理
System.err.println(ae.getMessage());
}
}
}
“`
catch和throw结合使用的情况在大型企业级应用中使用的非常频繁,使用方法:
1 通过日志记录异常发生时的情况
2 应用需要根据应用使用者传达某种提示