程序来源于生活,服务于生活。难免会出现异常。
李刚老师说:我们国内的程序员做开发时,往往只做了“对”的事。程序员开发程序的过程是一个创造的过程,这个过程需要有全面的考虑,仅做“对”的事实远远不够的。
话说远了,那异常的是什么呢?即阻止当前方法或作用域继续执行。
异常会导致程序不正常退出,用户数据丢失,所以我们就要进行适当的异常处理:将异常提示反映给用户和程序员,经过调整使它能正常运行,并经数据保存处理。
就像狼人和吸血鬼有一个共同的祖先一样,异常有两大类:Error和Exception,他们共同的祖先就是Throwable。当遇到error时一般就是终结者。例如虚拟机异常,内存溢出·····而Exception是可以通过异常处理解决的,通常包括编码、环境,用户操作,输入。Exception异常分为两大类Checked异常和Runtime异常(运行时异常)。所有的RuntimeException类及其子类的实例被称为Runtime异常,其他的被称为Checked异常。Runtime异常主要包括引用空对象,数组访问越界,算术不合法,类型转换出现错误等等。
JAVA的异常处理主要依赖于try、catch、finally、throw和throws五个关键字,try{}catch{},try代码块中放置可能引发异常的代码。多个catch块后开可以跟一个finally块,异常机制保证finally块一定会运行。throw用于抛出一个实际的异常,可以作为单独的语句使用,抛出一个具体的异常对象。throws主要在方法签名处使用,用于声明该方法可能抛出异常。
try...catch捕获异常,引用《疯狂JAVA讲义》的代码
public class Gobang
{
private String[][] board;
private static int BOARD_SIZE = 15;
public void initBoard()
{
board = new String[BOARD_SIZE][BOARD_SIZE];
for (int i = 0 ; i < BOARD_SIZE ; i++)
{
for ( int j = 0 ; j < BOARD_SIZE ; j++)
{
board[i][j] = "╋";
}
}
}
public void printBoard()
{
for (int i = 0 ; i < BOARD_SIZE ; i++)
{
for ( int j = 0 ; j < BOARD_SIZE ; j++)
{
System.out.print(board[i][j]);
}
System.out.print("\n");
}
}
public static void main(String[] args)throws Exception
{
Gobang gb = new Gobang();
gb.initBoard();
gb.printBoard();
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String inputStr = null;
while ((inputStr = br.readLine()) != null)
{
try
{
String[] posStrArr = inputStr.split(",");
int xPos = Integer.parseInt(posStrArr[0]);
int yPos = Integer.parseInt(posStrArr[1]);
if (!gb.board[xPos - 1][yPos - 1].equals("╋"))
{
System.out.println("您输入的坐标点已有棋子了,"
+ "请重新输入");
continue;
}
gb.board[xPos - 1][yPos - 1] = "●";
}
catch (Exception e)
{
System.out.println("您输入的坐标不合法,请重新输入,"
+ "下棋坐标应以x,y的格式");
continue;
}
gb.printBoard();
System.out.println("请输入您下棋的坐标,应以x,y的格式:");
}
}
}
try和catch捕获异常,如果在执行try和catch代码块时发生异常,系统会自动生成一个异常对象。如果程序没有catch块代码,程序就此退出。
在该程序中,如果出现异常,这个异常对象就会交给对应的catch代码块处理,然后使用continue忽略本次循环,开始执行下一次循环(正好可以用一个作业题:嗒嗒打车)这就保证了程序有足够的容错性---用户输入出错,程序会提示用户合法输入,然用户再次输入。
同样try后面可以跟多个catch代码块,如果说try...catch与if...else类似,那么加多个catch代码块就可能类似于switch...case。
常用异常处理逻辑:
IndexOutOfBoundsException:输入参数不够,将发生数组越界异常;
NumberFormatException:输入参数不是数字而是字母,将发生数字格式异常;
ArithmeticException:除数是零,不合法行为算术异常。
还有一个顺序问题,遇到异常都是先子类后父类。
public class OverrideThrows
{
public void test()throws IOException
{
FileInputStream fis = new FileInputStream("a.txt");
}
}
class Sub extends OverrideThrows
{
public void test()throws Exception
{
}
}
子类中抛出Exception。是父类中抛出异常IOException类的父类,程序无法通过编译