Java 中的异常定义
(Exception)又称为例外,是一个在程序执行期间发生的事件,它中断正在执行的程序的正常指令流。为了能够及时有效地处理程序中的运行错误,必须使用异常类。
异常的分类
要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:
检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。 必须要try…catch, 或者往外抛。大部分的时候,都是写IO相关代码的时候,用的比较多。
运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。比如: NullPointerException,ClassNotFoundException,ArithmeticException。(继承了RuntimeException的异常,就可以在编译的时候,忽略,不需要try…catch)
错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
异常处理
遇到异常以后,程序会停止运行,所以控制台看不到测试打印的“看看”
package com.javabase;
public class ExceptionTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// try{
int a=4/0;
// }catch(ArithmeticException e){
// System.out.println("异常处理的方式:"+e.getMessage());
// }
System.out.println("看看");
}
}
运行结果:
Exception in thread “main” java.lang.ArithmeticException: / by zero
at com.javabase.ExceptionTest.main(ExceptionTest.java:8)
通过try{}catch(){} 处理一下,处理以后,程序遇到异常,会继续往下执行,可以在控制台看到“看看”
package com.javabase;
public class ExceptionTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
int a=4/0;
}catch(ArithmeticException e){
System.out.println("异常处理的方式:"+e.getMessage());
}
System.out.println("看看");
}
}
运行结果:
异常处理的方式:/ by zero
看看
finally 无论有无异常,都会执行finally里面的代码。
没有异常的情况
package com.javabase;
public class ExceptionTest2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
int a=4/2;
}catch(ArithmeticException e){
System.out.println("异常处理的方式:"+e.getMessage());
}finally{
System.out.println("这里是finally");
}
System.out.println("看看");
}
}
执行结果:
这里是finally
看看
有异常的情况
package com.javabase;
public class ExceptionTest2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
int a=4/0;
}catch(ArithmeticException e){
System.out.println("异常处理的方式:"+e.getMessage());
}finally{
System.out.println("这里是finally");
}
System.out.println("看看");
}
}
执行结果:
异常处理的方式:/ by zero
这里是finally
看看
有return 和 finally的情况。
其实是会先触发return, 然后暂停return 去执行完finally里面的代码,再继续return.
所以下面的列子: 可以看到 catch 和finally里面的打印语句,但是最后那个“看看” 控制台没有打印,因为return了,就停止了。
package com.javabase;
public class ExceptionTest3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ExceptionTest3 t=new ExceptionTest3();
t.test1();
}
public String test1(){
try{
int a=4/0;
}catch(ArithmeticException e){
System.out.println("异常处理的方式:"+e.getMessage());
return "有错";
}finally{
System.out.println("这里是finally");
}
System.out.println("看看");
return "到底了";
}
}
运行结果:
异常处理的方式:/ by zero
这里是finally
主动抛异常
package com.javabase;
public class ExceptionTest4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ExceptionTest4 t=new ExceptionTest4();
try{
t.test1(0);
}catch(IllegalArgumentException i){
System.out.println("主动抛的错误*****"+i.getMessage());
}
System.out.println("看看");
}
public void test1(int a){
if(a==0){
//主动抛出异常
throw new IllegalArgumentException("如果是0就报错");
}
}
}
运行结果:
主动抛的错误*****如果是0就报错
看看
自定义异常
package com.javabase;
//如果继承: RuntimeException 编译的时候,就可以忽略
//如果直接继承Exception, 在使用这个自定义的异常是,必须编译处理异常
public class ExceptionTest5 extends RuntimeException {
//构造方法:用来放在new 后面 创建对象/实列
//构造方法 (1)方法名字和类名一样 (2) 没有返回值
//无参构造方法
public ExceptionTest5() {
super();
}
//有参构造方法
public ExceptionTest5(String message) {
super(message);
//相当于:message=message+"Bsea不同意"
message+="自己不同意";
}
public String getMessage() {
return super.getMessage()+"**********来自自定义异常";
}
}
测试:
package com.javabase;
public class ExceptionTest6 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ExceptionTest6 t=new ExceptionTest6();
try{
t.test1(0);
}catch(ExceptionTest5 i){
System.out.println("主动抛的错误*****"+i.getMessage());
}
System.out.println("看看");
}
public void test1(int a){
if(a==0){
//主动抛出异常(必须是Throwable的子类)
throw new ExceptionTest5("如果是0就报错");
}
}
}
运行结果:
主动抛的错误*****如果是0就报错**********来自自定义异常
看看