1.五个关键字
1.try:尝试捕获异常,具体的下面讲述
2.catch:当try捕获到异常了,系统会自动生成一个异常信息,这个异常信息就给catch,形象的说我抓住了这个异常。
3.throw:主动的抛出一个异常
情况一:我发现了一个我处理不了的 并且会导致我程序不正常运行的错误,于是我将这个异常抛出去了。(抛给谁了?这个视情况而定)
情况二:我发现了一个不太对的地方会影响我今后的程序运行,为了避免更大的错误产生,我先主动的提出(抛出)这个“问题”
4.throws:方法声明 会抛出这样的异常,用于自定义异常。(初学者 可以暂时绕过)
5.finally:
无论是否发生异常,程序必须执行的代码块。例如:经典的关闭数据库连接例子。多用于执行清理工作。
finally看似很“权威”(必须执行),但是System.exit(1);会让它丧失这个权威性。
2.try+catch
1.联合出击保证程序正常运行。
2.理解:
我们希望写出这样的程序:if(程序正常){我的操作} else{处理不正常}
但是这个程序正常太泛泛了 我们没办法定义它或者枚举它,于是我们用try去监视我们的操作是否正常,
当他不正常的时候,我们抓住这个不正常的情况 处理它。
try-catch 就是在做这么一件有意义的事。
3.注意(新手看不懂可以先绕过):
1.catch可以有多个,谁能抓住谁抓,抓不住就让别人去抓,但是这个是需要层级的(范围小的先catch)
2.try块中的变量只能在try中使用。
3.java7中提供了一次catch多个异常的方式,每个异常使用|分割(注意只有在jdk7下才能使用)
4.java7下的AutoCloseable接口可以使得程序简化有兴趣可自己百度或者查看java api
4.Exception的几个方法(见例子)
5.自定义一个异常:
1.上文说过不肯能枚举所有的异常情况,即便枚举了,但是你也不能冲破认知差异性。(在大象的世界里人类就是异类)
2.定义一个拥有自己业务逻辑的异常类
3.实现方式:继承Exception 或者他的子类
package com.cxy.exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.List;
/**
* @author cxy
*/
public class ExceptionTest
{
public static void main(String[] args)
{
try
{
List l=null;
l.get(0);
}catch(NullPointerException|ArrayIndexOutOfBoundsException e) //注意:这里只能java7用,如果你不是java7请去掉一个异常
{
System.out.println("我抓住了一个异常");
System.out.println("异常信息:"+e.getMessage());
e.printStackTrace(); //打印异常的跟踪栈信息
}
System.out.println("=======================");
/* throw
* 用途:
* 1.抛出一个我处理不了的异常
* 2.提前发现问题避免更大的问题发生(实践中得来)
* 一个人要盖别墅,后经发现他选址在太平洋中间,于是我抛出了这个问题,避免后面砂石料,工程设计都做好了 发现根本没法建。
* 效果:导致程序或者方法终止(如果不catch这个异常的话)
* */
try
{
throw new Exception("没事抛着玩"); //主动抛出一个异常
} catch (Exception e)
{
e.printStackTrace();
}
System.out.println("=======================");
//throws的用法
try
{
test();
} catch (NullPointerException e)
{
System.out.println("catch住了test方法抛出的异常");
}
System.out.println("=======================");
//finally用法
FileInputStream fis=null; //这是一个输入流 相关的知识请见后续文章
try
{
/* 这里会出现找不到cxy.txt这个文件错误
* 这里有个问题 无论异常产生与否 我们都需要将fis关闭
* java7之前 我们都是使用finally来处理这类的问题,无论是否发生异常都要执行的操作
* java7开始,AutoCloseable接口可以不必使用finally来处理这个问题(如果有时间我会写一篇相关的文章)
*/
fis = new FileInputStream("cxy.txt");
} catch (FileNotFoundException e1)
{
e1.printStackTrace();
}finally
{
try
{
fis.close();
} catch (Exception e)
{
//呵呵 包括这里都套着一个try,因为 程序怕遇到fis是null 或者 io异常
e.printStackTrace();
}
}
System.out.println("=======================");
//自定义异常类
try
{
throw new MyException("中文异常信息");
} catch (MyException e)
{
e.printChineseMsg();
}
System.out.println("虽然有很多异常,但是我正常完结了~");
}
/** 提前声明 我这个方法可能会抛出什么样的异常,请调用者自己处理
*/
public static void test() throws NullPointerException
{
throw new NullPointerException(); //抛出一个null异常
}
}
//自己定义的异常
class MyException extends Exception
{
public MyException(){}
public MyException(String msg)
{
super(msg);
//当然 这里你可以加一些日志的操作
}
/**
* 我们期望的能看懂的中文异常信息
*/
public void printChineseMsg()
{
System.out.println("异常信息:"+this.getMessage());
}
}
概述:
1.异常给初学者的感觉(笔者当时就是这个感觉,不知道其他人是否有共鸣?)
1.异常是个什么东西?理解不了
2.很复杂
3.异常很“简陋”,没什么用
4.我保证我写的程序正确性和健壮性 就用不到它了
2.解释:
1.异常是java用来处理程序错误的一种机制,所谓的错误不是语法错误,而是一些不可预期的运行时错误(主要)
2.只要你会用,其实异常并不复杂(相对泛型啊 线程啊 来说)
3.恰恰相反,异常是十分强大的,前提是你得会用
4.记住你是人不是神,你不可能枚举出所有的错误情况,
即便你有这个能力,真这么做了 你的程序会相当的臃肿(写1000行程序,800行在处理所有可能产生的情况,无论这种情况重要与否)。
3.异常存在和使用的意义
1.弥补我们人类思维缜密性的不足,处理那些不可预知的错误,保证程序正常运行。
2.简化开发,你不用去枚举所有可能出现的情况,只需要做和业务逻辑相关的有用的,其他不重要的(相对业务逻辑来说)让异常帮你搞定。
4.java中把非正常情况分为异常(Exception)和错误(Error),这两个类都是Throwable的子类
异常(Exception):我们主要讨论的,程序运行时候产生的错误。
错误(Error):虚拟机级的错误,一般我们无能力从程序的角度去处理他。
5.下面我们通过感官来认识一下异常
package com.cxy.exception;
import java.util.List;
/** 几种常见异常的演示(异常概述)
* @author cxy
*/
public class SomeException
{
public static void main(String[] args)
{
try
{
test(21,0);
}catch(Exception e)
{
e.printStackTrace();
}
//访问索引是5的元素,会抛出数组越界的异常 ArrayIndexOutOfBoundsException
try
{
//实际 下面这句没有必要在这里 但是为了结构层次清楚 我将这行放到了这个位置
String[] array={"A","B","C","D","E"};
System.out.println(array[5]);
}catch(Exception e)
{
e.printStackTrace();
}
try
{
//实际 下面这句没有必要在这里 但是为了结构层次清楚 我将这行放到了这个位置
List l=null; //初学者习惯这样初始化一个List
l.get(0); //尝试访问一个空的对象,会抛出空指针(引用)异常 NullPointerException
//当然 你会说 我不会这么傻去访问一个null的方法,这个例子只是一个简单的缩影,真实程序 可能你调用方法的时候并没有预计到这时候他是null
}catch(Exception e)
{
e.printStackTrace();
}
System.out.println("程序正常运行");
}
/**
* 当b是0的时候会抛出算数错误异常 ArithmeticException
*/
public static void test(int a,int b)
{
System.out.println("a/b="+a/b);
}
}
结束语:
1.上面的程序演示了3个比较常见的异常,让大家从感官上认识一下异常
2.程序虽然有3个异常,但是大家发现 最后仍然打印了“程序正常运行”,这就是异常价值体现之一(保证程序正常运行)
3.控制台打印了各种异常的信息,初学者开发的时候 要注意这些异常,这也是提高开发效率的方法之一。
异常追踪栈(StackTrace)
1.运行下面的例子,查看打印的异常信息。
2.会发现 method3的异常 一层一层的抛 最后抛到了main方法
3.很多初学者看到呼啦啦一堆异常信息后就有抵触情绪或者觉得很复杂
其实不然,学会观察异常信息,会对今后的工作有很大的帮助
不要觉得复杂,复杂是因为你没有看习惯,如果看习惯了会觉得异常信息的层次脉络很清楚,并且很实用