20160723 异常/
来源:互联网 发布:淘宝电器以旧换新 编辑:程序博客网 时间:2024/05/17 01:10
异常:
程序在执行过程中出现不正常的现象
import java.util.Scanner;class ExceptionDemon1 {public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入除数: ");int b=sc.nextInt();System.out.println("请输入被除数: ");int a=sc.nextInt();int num=devide(a,b);//System.out.println("商为: "+num);}<pre name="code" class="java">
//除法计算public static int devide(int a,int b){ return a/b;// }}
/*请输入除数:0请输入被除数:1Exception in thread "main" java.lang.ArithmeticException: / by zero at ExceptionDemon1.devide(ExceptionDemon1.java:20) at ExceptionDemon1.main(ExceptionDemon1.java:13)请按任意键继续. . .*/
主方法是怎么处理异常的?
主方法在处理异常时是没有对异常做相关的处理操作,
仅仅是将异常的信息,以及相关的错误代码打印到控制台上
仅仅是将异常的信息,以及相关的错误代码打印到控制台上
class ExceptionDemon2 {public static void main(String[] args) {int []array={1,4,6,8};for (int i=0;i<array.length ;i++ ){System.out.println(array[i]);}}}
我们应该怎么去处理异常?
由于异常的信息特别多,我们需要将异常的信息进行封装,我们之前学过面向对象,在这里可以采用面向对象的思维去对异常进行封装
但是异常也分为严重与不严重的情况,通过面向对象的思维模式,可以将异常的这两种情况提取出来进行封装,在java中已经进行了一个体系
其顶层是Throwable
Throwable类 是java语言中所有错误和异常的超类
Throwable
Error:不在我们处理范围内的异常,属于严重的错误
Exception:在我们处理范围内的异常,能够通过我们进行处理
实例1:
1.我们骑自行车出去玩,自行车的链条坏了----可处理范围内
2.我们骑自行车出去玩,路断了====不在处理范围内
实例2:
1.得了感冒----可以买要吃解决
2.得了癌症----吃药是无法解决的,属于严重错误
class ExceptionDemon3 {public static void main(String[] args) {byte [] by=new byte[1000*1024*1024];System.out.println(by); /*Exception in thread "main" java.lang.OutOfMemoryError: Java heap space---内存溢出 at ExceptionDemon3.main(ExceptionDemon3.java:27)*/}}
*Throwable(可抛出;异常;对象)有哪些方法?
getMessage()--返回此Throwable的详细消息字符串(获取异常信息返回字符串)
printStackTrace()--将此 throwable 及其追踪输出至标准错误流。(获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void)
printStackTrace(PrintStream s)--将此 throwable 及其追踪输出到指定的输出流。 (通常用该方法将异常内容保存在日志文件中,以便查阅)
字节流
printStackTrace(PrintWriter s)--将此 throwable 及其追踪输出到指定的 PrintWriter "自己去试"
字符流
toString()--返回此 throwable 的简短描述(获取异常类名和异常信息,返回字符串)
**自己怎么处理异常?
1.try(发现异常)--catch(处理异常) finally(处理) catch是必带的,仅仅try是不可以的
a.try...catch 一发现一处理
b.try...catch...catch... 一发现多处理(无限多)
**原则:先处理小的,再处理大的
import java.util.Scanner;import java.lang.ArithmeticException;import java.lang.ArrayIndexOutOfBoundsException;//导入异常class ExceptionDemon4{public static void main(String[] args) { //扫描控制台输入/*Scanner sc=new Scanner(System.in);System.out.println("请输入除数: ");int b=sc.nextInt();System.out.println("请输入被除数: ");int a=sc.nextInt();*/ /* try//发现异常 //--- { int num=devide(a,b);// System.out.println("商为: "+num); int[]array={1,3}; System.out.println(array[2]);//取不到 } */ /* catch(ArithmeticException e) //----- { System.out.println("报错了"); } catch(ArrayIndexOutOfBoundsException e) //----- { System.out.println("数组脚标越界"); }*/ /* Exception in thread "main" java.lang.ArithmeticException: / by zero at ExceptionDemon1.devide(ExceptionDemon1.java:20) at ExceptionDemon1.main(ExceptionDemon1.java:13) */ try {int[]array={1,3};System.out.println(array[2]);// - } catch (Exception e)//catch它的父类,下面任何子类报出来的时候,我们都能捕捉到//超级父类Throwable也可以,但一般会这么做,因为会包含Error的错误,Error也捕捉不到 { System.out.println("报错了"); // String message=e.getMessage();//获取异常信息返回字符串 // System.out.println(message);//2 // e.printStackTrace();//不返回什么,直接打印到控制台(获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void) //报错了 //java.lang.ArrayIndexOutOfBoundsException: 2--① //at ExceptionDemon4.main(ExceptionDemon4.java:71) System.out.println(e.toString());//(获取异常类名和异常信息,返回字符串) //java.lang.ArrayIndexOutOfBoundsException: 2--① } System.out.println("******结束******");//正常打印 /* Exception in thread "main" java.lang.ArithmeticException: / by zero at ExceptionDemon1.devide(ExceptionDemon1.java:20) at ExceptionDemon1.main(ExceptionDemon1.java:13) */} //除法计算public static int devide(int a,int b){ return a/b;// } }**①原则:先处理小的,再处理大的
②try处理的优先级问题
③try 和 finally 配合问题
a.
b.
c.try...catch...finally(里面的内容为-无论是否异常-必须执行!)
放在finally里执行的内容一般为:资源必须关闭等操作
d.try..catch...catch... finally
e.try...finally
④为什么不报错的代码我们不一起放到try中?
(try中要报错的系统会预分配内存)
放在try中的内容,在执行过程中java虚拟机会进行分配相应的空间
如果把没有报异常的代码一并放入try中,会降低程序的执行效率,所以通常不报错的代码不放在try中
*/
import java.util.Scanner;import java.lang.ArithmeticException;import java.lang.ArrayIndexOutOfBoundsException;//导入异常class ExceptionDemon5{public static void main(String[] args) { //扫描控制台输入Scanner sc=new Scanner(System.in);System.out.println("请输入除数: ");int b=sc.nextInt();System.out.println("请输入被除数: ");int a=sc.nextInt(); /* try//发现异常 //--- { int num=devide(a,b);// System.out.println("商为: "+num); //int[]array={1,3}; //System.out.println(array[2]);//取不到 } */ /* catch(ArithmeticException e) //----- { System.out.println("报错了"); } catch(ArrayIndexOutOfBoundsException e) //----- { System.out.println("数组脚标越界"); } catch(Exception e) //----- { System.out.println("展现的是父类异常"); }*/System.out.println("------------------分隔符----------------------");/* try//发现异常 //--- { int num=devide(a,b);// System.out.println("商为: "+num); int[]array={1,3}; System.out.println(array[2]);//取不到 } catch(ArrayIndexOutOfBoundsException e) //----- { System.out.println("数组脚标越界"); } catch(Exception e) //----- { System.out.println("展现的是父类异常"); } finally { System.out.println("最终执行,必须执行我"); }*/System.out.println("------------------分隔符1----------------------"); /* try//发现异常 //--- { int[]array={1,3}; System.out.println(array[2]);//取不到 } catch(ArrayIndexOutOfBoundsException e) //----- { System.out.println("数组脚标越界"); } finally { System.out.println("最终执行,必须执行我1"); } try//发现异常 //--- { int num=devide(a,b);// System.out.println("商为: "+num); } catch(Exception e) //----- { System.out.println("展现的是父类异常"); } finally { System.out.println("最终执行,必须执行我2"); }*/System.out.println("------------------分隔符2----------------------"); //System.exit(0);//相当于是程序式的直接中断,之下的内容就不会被执行 try//发现异常 //--- { int num=devide(a,b);// System.out.println("商为: "+num); System.exit(0);//放在这里也可以,无异常时,num输出,finally也不会被执行,没有"结束" //但是异常时,直接跳到finally执行,输出printStackTrace(),没有"结束" } finally { System.out.println("最终执行,必须执行我2"); }//异常的话,执行依然报错,所以没有"结束"System.out.println("******结束******");//正常打印} //除法计算public static int devide(int a,int b){ return a/b;// } }
异常的第二种处理方式:
自己不处理该异常,将该异常[抛出,谁调用谁处理抛异常的关键字是throws
*主函数调用了这个异常,主函数两种处理方式
①try..catch 处理掉
②直接抛掉不再处理(不处理,谁调用谁处理)
*处理异常的两种方式到底哪一种好?
原则:能处理则处理,处理不好则抛出
class ExceptionDemon6{public static void main(String[] args) throws Exception//下边也不想处理了,直接交给java虚拟机处理---②{//int num=devide(10,2);---零//System.out.println(num);//5 //int num=devide(10,0);---零//System.out.println(num);//不能除以0 //0 //int num=devide(10,1);---②//System.out.println(num);//10 int num=devide(10,0);//---②System.out.println(num);//报异常,printStackTrace()类型 /* try //---① {int num=devide(10,0);System.out.println(num); } catch (Exception e) {System.out.println("不能除以0");//输出"不能除以0" }*/ /* try //---① {int num=devide(10,1);System.out.println(num); } catch (Exception e) {System.out.println("不能除以0");//输出="10" }*/}/*public static int devide(int a,int b)--零{ int result=0; try {result=a/b; } catch (ArithmeticException e) { System.out.println("不能除以0"); } return result; }*///System.out.println("----------分隔符-------------"); public static int devide(int a,int b)throws Exception//---①,② //ExceptionDemon6.java:13: 错误: 未报告的异常错误Exception; 必须对其进行捕获或声明以便抛出{ /*int result=0; try {result=a/b; } catch (ArithmeticException e) { System.out.println("不能除以0"); } return result;*/ return a/b; }}
throws 和throw
throws用于标识函数暴露出的异常
throw用于抛出异常对象
*区别:
1. throws用在函数上,后面跟"异常类名"
throw用在函数内,后面跟"异常对象"
2.throws可以单独使用
throw必须与throws组合使用(RuntimeException)
处理异常:①抛给java虚拟机②try...catch
还有一种:直接抛掉,不想交给谁去处理
**RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类,
可能在执行方法期间抛出但未被捕获的 RuntimeException 的任何子类都无需在 throws 子句中进行声明。//--在大数据运用中缩短排查错的时间
今后会教怎么用这种方式去排查错误,缩短查找时间
RuntimeException与Exception的区别:
1.Exception是编译时会检测的异常,是需要编写代码进行处理的
2.RuntimeException是运行时的异常,在编译过程中不检测
*/
class ExceptionDemon7{/*public static void main(String[] args) throws Exception //--调用的是throws{ int num=devide(10,0);System.out.println(num); } public static int devide(int a,int b)throws Exception { return a/b; }*/ //---------------------------------------------------------------------------------------- /* public static void main(String[] args) throws Exception { int num=devide(10,0);System.out.println(num);//10(非异常) } public static int devide(int a,int b) throws Exception{ int result=0; try {result=a/b; } catch (ArithmeticException e) { throw new Exception("不能除以0");//带有了构造函数--异常的话,printStackTrace(),异常名称为"不能除以0" } return result; }*///------------------------------------------------------------------------------------ /* public static void main(String[] args) { try {int num=devide(10,0);System.out.println(num);//10(非异常) } catch (Exception e) {System.out.println("不能除以0");//输出"不能除以0"(异常) } //int num=devide(10,1);//System.out.println(num); } public static int devide(int a,int b) throws Exception{ int result=0; try {result=a/b; } catch (ArithmeticException e) { throw new Exception("不能除以0");//带有了构造函数 } return result; }*///---------------------------------------------------------------------/* public static void main(String[] args) throws Exception{// try // {//int num=devide(10,0);//System.out.println(num);//10(非异常) // } // catch (Exception e) // {//System.out.println("不能除以0");//输出"不能除以0"(异常) // } int num=devide(10,0);System.out.println(num); } public static int devide(int a,int b) throws Exception// ---------// 到时候抛的不是这个异常,而是其他异常,从114行抛出时,可以有效的帮助我们在前面的代码中查找错误{ int result=0; try {result=a/b; } catch (ArithmeticException e) { throw new Exception("不能除以0");//带有了构造函数--异常的话,printStackTrace(),异常名称为"不能除以0" //可以帮我们达到异常的转换目的 } return result; }*///--------------------------------------------------------------------------------------------------------------- public static void main(String[] args) //不抛--------------抛出的是RuntimeException的时候,主函数中谁调用都不需再处理, // 也不需要再进行一个声明{/* try {int num=devide(10,0);System.out.println(num);//10(非异常) } catch (Exception e) {System.out.println("不能除以0");//输出"不能除以0"(异常) }*/ int num=devide(10,0);System.out.println(num); } public static int devide(int a,int b) //不抛{ int result=0; try {result=a/b; } catch (ArithmeticException e) { throw new RuntimeException("不能除以0");//带有了构造函数--异常的话,printStackTrace(),异常名称为"不能除以0" //可以帮我们达到异常的转换目的 } return result; } //输出为:Exception in thread "main" java.lang.RuntimeException: 不能除以0 //at ExceptionDemon7.devide(ExceptionDemon7.java:154) //at ExceptionDemon7.main(ExceptionDemon7.java:140)}
finalize 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
子类重写 finalize 方法,以配置系统资源或执行其他清除。
final finally finalize三者之间的区别?
final:可以有来修饰类,成员变量,成员方法;如果用来修饰类,则此类不能被继承
如果用来修饰成员变量,则此变量不能被改变,如果用来修饰成员方法,
则此方法不能被重写
finally:属于是异常体系中的一个关键词,一般用于释放资源,永远被执行
但特殊情况System.exit(0)除外
finalize:是Object类中的一个方法,当垃圾回收器确定不存在对该对象的更多引用时,由对象
的垃圾回收器调用此方法
class FinallyDemon8{public static void main(String[] args) {int final String line="测试";// -----try{int value=devide(a,b);System.out.println("商为:"+value);}finally (){System.out.println("必须执行我");}} //除法计算public static int devide(int a,int b){ return a/b; }}
/*
总结:
Exception异常体系在继承中的表现情况?a.在继承过程中,子类继承方法不能抛比父类中更多更大的异常
b.但可以抛父类中异常的子类异常或是相同的异常,一般是直接抛和父类中相同的异常
*/
/*class Demon
{
public static void printTest()throws ClassNotFoundException
{
System.out.println("调用我会抛异常");//方法抛出了一个异常-----①
//ExtendDemon9.java:12: 错误: 未报告的异常错误ClassNotFoundException; 必须对其进行捕获或声明以便抛出
}
}
class ExtendDemon9 extends Demon
{
public static void main(String[] args) throws Exception//加上(抛出最大的异常)此句后,输出①
// ----------------
{
printTest();
}
}*/
//-----------------------------------------------------------
/*
第二项中
a.throws NotBoundException--ExtendDemon9.java:36: 错误: 找不到符号
b.throws Exception---ExtendDemon9.java:44: 错误: ExtendDemon9中的printTest()无法覆盖Demon中的printTest()
** 在子类中不能抛比①中异常还大的异常,可以抛比它小的异常吗?
*/
/*class Demon
{
public static void printTest()throws ClassNotFoundException//--①
{
System.out.println("调用我会抛异常");
}
}
class ExtendDemon9 extends Demon
{
public static void main(String[] args) throws Exception
{
printTest();
}
public static void printTest() //throws NotBoundException与throws Exception//都拋不过去
// ------------------------
{
System.out.println("我是子类");//重写之后,输出"我是子类"
}
}*/
//*************************************************************************************
//** 在子类中(②)不能抛比①中异常还大的异常,可以抛比它小的异常吗?(①与②的抛出交换)
// A: 只能是相同或是父类中异常的子类 (绝对不能抛上面"没有"的异常)
class Demon{public static void printTest()throws Exception//--①{System.out.println("调用我会抛异常"); }}class ExtendDemon9 extends Demon{public static void main(String[] args) throws Exception{printTest();}public static void printTest()throws ClassNotFoundException//--②// {System.out.println("我是子类");//输出:我是子类 }}
/* Q1:为什么要采用自定义异常?(有了java体系定义的那一套异常,为什么还要自定义) A1:因为java定义的异常是常用的异常,根据我们的业务需求,是无法全部满足的 所以需要自定义异常 Q2;怎么定义自定义异常? A2:继承Exception或RuntimeException(抛了后者这个异常,不需要在编写代码中做任何处理,但一般很少用这个异常,一般处理一些特殊跟踪异常才会用到)根据自己的需求,报什么异常,为了跟踪什么错误,然后我们就自己直接自定义异常*//*class MyException extends Exception{private int number;public MyException(String message,int number){ super(message); this.number=number; } public int getNumber(){ return number; }}class Demon{public void devide(int a,int b) throws MyException//如果没这个抛出,则ExceptionDemon10.java:30: 错误: 未报告的异常错误MyException; 必须对其进行捕获或声明以便抛出{ if (b<0) { throw new MyException("除数不能为0",b); } else { System.out.println("商为:"+a/b); } }}class ExceptionDemon10{public static void main(String[] args) {Demon demon=new Demon();demon.devide(2,3);//ExceptionDemon10.java:44: 错误: 无法将类 Demon中的方法 devide应用到给定类型; //加上"2,3"后,ExceptionDemon10.java:44: 错误: 未报告的异常错误MyException; 必须对其进行捕获或声明以便抛出}}*///------------------------------------------------------------------------------------------------/*class MyException extends Exception//------------------这里是自定义的异常{private int number;public MyException(String message,int number){ super(message); this.number=number; } public int getNumber(){ return number; }}*/class MyRuntimeException extends RuntimeException{ public MyRuntimeException(String message){ super(message); }}/*class Demon{public void devide(int a,int b) throws MyException{ if (b==0) { throw new MyException("除数不能为0",b);//抛出了"除数不能为零"+0 } else { System.out.println("商为:"+a/b); } }}*/class Demon1{public void devide(int a,int b)throws MyRuntimeException{ if (b==0) { throw new MyRuntimeException("除数不能为零");//多了",b",//ExceptionDemon10.java:98: 错误: 无法将类 MyRuntimeException中的构造器 MyRuntimeException应用到给定类型; } else { System.out.println("商为:"+a/b); } }}class ExceptionDemon10{public static void main(String[] args) //throws MyException//此处相对于上为新增加--不抛,因为要打印异常信息{/*try{Demon demon=new Demon(); //demon.devide(4,2);//商为:2 demon.devide(4,-0);//0----除数不能为0//demon.devide(4,-2);//商为:-2}catch (MyException e){System.out.println(e.getNumber()+"----"+e.getMessage());}*/Demon1 demon1=new Demon1();//上面的已经抛了,这里不需要再做声明了//demon1.devide(6,1);//6demon1.devide(6,0);//Exception in thread "main" MyRuntimeException: 除数不能为零 //at Demon1.devide(ExceptionDemon10.java:98) //at ExceptionDemon10.main(ExceptionDemon10.java:126) //以上为直接交给java虚拟机进行的处理}}
0 0
- 20160723 异常/
- 异常
- 异常!
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- 异常
- Centos下 samba服务器配置,windows、linux文件共享
- 数组遍历组合
- 编程小记
- VIM操作
- NSArray不用遍历能否判断一个对象是否存在在数组里面?
- 20160723 异常/
- 主题模型TopicModel:Unigram、LSA、PLSA主题模型详解
- ubuntu14.04+ROS indigo+kinectV1 骨骼点检测
- Window,WindowManager学习总结
- 多线程
- 中文乱码问题,Eclipse能正常显示,但在tomcat部署工程中不行
- HDU 1532 Drainage Ditches (最大流模板)
- sunday算法和自己关于字符串匹配的一些思考
- struts2表单提交的中文参数后台乱码问题解决