异常处理
当我们程序出现问题时,在java中,我们使用异常机制进行错误处理;
模式:1.在方法中,抛出异常,(在方法后面加 throws Exception)
2. 在调用时,捕获异常;(用 try ... catch ... 来捕获异常)
抛出异常:在检测到错误发生时,抛出异常对象
int str( String s) throws Exception
{
if ( 错误1发生 )
throw new Exception("错误1");
if( 错误2发生 )
throw new Exception("错误2");
}
捕获异常:
try{
可能抛出异常的代码1
可能抛出异常的代码2
..........
}catch(Exception e){
进行异常处理
}
例子:我们写一个把字符串转成数字的程序,就可能出现以下情况:
1.字符串可能含有字母;
2.用int保存数字,数字太大就会出现越界;
下面,我们通过写这个程序,以及处理异常情况来了解java的异常处理机制。
情况一:我们用 if...else 来处理以上情况。
/******Converter.java******/
package my;
public class Converter
{
public int status = 0;
public int str2int (String str)
{
status = 0;
if(str.length()>11)
{
status = -2; // 第2种情况
return 0;
}
int result = 0;
for(int i=0; i<str.length(); i++)
{
char ch = str.charAt(i);
if( ! isValid(ch) )
{
status = -1; // 第1种情况
return 0;
}
result = result * 10 + (ch - '0');
}
return result;
}
private boolean isValid(char ch)
{
if(ch >= '0' && ch <= '9')return true;
if(ch == '-') return true;
return false;
}
}
在main函数中调用:
/*****Test.java*****/
package my;
public class Test
{
public static void main(String[] args)
{
Converter conv = new Converter();
int result = conv.str2int("201k8");
if(conv.status == 0)
{
System.out.println("转换结果: " + result);
}
else
{
if(conv.status == -1)
System.out.println("非法字符");
else if(conv.status == -2)
System.out.println("超出范围");
}
}
}
可以看出,用if...else也可以处理错误,但是非常繁琐,而且情况多的时候处理起来非常麻烦。
情况二:添加try...catch
把Converter.java改写如下
/******Converter.java******/
package my;
public class Converter
{
public int str2int (String str) throws Exception
{
if(str.length()>11)
{
Exception ex = new Exception("超出范围");//抛出异常
throw ex;
}
int result = 0;
for(int i=0; i<str.length(); i++)
{
char ch = str.charAt(i);
if( ! isValid(ch) )
throw new Exception("非法字符"); //抛出异常
result = result * 10 + (ch - '0');
}
return result;
}
private boolean isValid(char ch)
{
if(ch >= '0' && ch <= '9')return true;
if(ch == '-') return true;
return false;
}
}
把Test.java改写如下
/********Test.java***********/
package my;
public class Test
{
public static void main(String[] args)
{
Converter conv = new Converter();
try {
int result = conv.str2int("201k8");
System.out.println("正常:" + result);
}
catch( Exception e)
{
System.out.println(e.getMessage());
}
System.out.println("exit");
}
}
在Converter.java中抛出异常,在调用时如果try中的代码有错误,就会在catch中捕获到。
自定义异常
现在,我们想更精确的处理错误,想知道错误的具体原因:
若是“非法字符”异常,需要知道哪个字符输入错误了;若是“长度超限”异常,需要知道输入了多少个字符。
可以通过自定义异常解决
try ... catch ... catch ... 可以匹配不同类型的异常
try { }
catch ( AException e1) { }
catch ( BException e2) { }
catch ( Exception ex) { } // 肯定匹配
1 自定义异常:用于携带出错时的具体信息
2 按类型捕获:对不同的异常类型做不同的处理
添加两个文件 InvalidCharException.java 和 TooLargeException.java 来处理“非法字符”和“长度超限”
/******InvalidCharException.java*******/
package my;
public class InvalidCharException extends Exception
{
public int pos; // 非法字符出现的位置
public char ch; // 非法字符
public InvalidCharException(int pos, char ch)
{
this.pos = pos;
this.ch = ch;
}
@Override
public String getMessage()
{
return "非法字符'" + ch + "',位置:" + pos;
}
}
/******TooLargeException.java*************/
package my;
// 当字符串太长时,抛出此异常
public class TooLargeException extends Exception
{
public int length; // 实际长度
public TooLargeException(int length)
{
this.length = length;
}
@Override
public String getMessage()
{
return "字符串太长(" + length + ")";
}
}
把test.java 和 Converter.java 改写如下:
/******Converter.java*******/
package my;
public class Converter
{
public int str2int (String str) throws Exception
{
if(str.length()>11)
{
Exception ex = new TooLargeException(str.length());
throw ex;
}
int result = 0;
for(int i=0; i<str.length(); i++)
{
char ch = str.charAt(i);
if( ! isValid(ch) )
throw new InvalidCharException(i, ch);
result = result * 10 + (ch - '0');
}
return result;
}
private boolean isValid(char ch)
{
if(ch >= '0' && ch <= '9')return true;
if(ch == '-') return true;
return false;
}
}
/*********Test.java**************/
package my;
public class Test
{
public static void main(String[] args)
{
Converter conv = new Converter();
try {
int result = conv.str2int("201k8");
System.out.println("正常:" + result);
}
catch( InvalidCharException e1)
{
System.out.println(e1.getMessage());
}
catch ( TooLargeException e2)
{
System.out.println(e2.getMessage());
}
catch( Exception e)//若以上错误都不执行,就会执行这个
{
System.out.println(e.getMessage());
}
System.out.println("exit");
}
}
这时,我们在main方法中就可以通过catch不同类型的错误进行处理。