------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Throwable
Error
通常出现重大问题:如运行的类不存在或者内存溢出等
不编写针对代码对其处理
Exception
在运行时运行出现的一些情况,可以通过try,catch,finally
Exception和error的子类名都已父类名作为后缀
例:被除数为零
异常:就是程序在运行时出现不正常情况
问题也是实现生活中的一个具体的事物,也可以通过java的类的形式进行描述.并封装成对象,其实就是java对不正常情况进行描述后的对象体现
两种:
一种是严重的问题,
一种是非严重的问题
1.对于严重的,java通过Error类进行描述(例:疾病中不可治愈的),对于Error一般不编写针对性的代码对其进行处理
2.对于非严重的,java通过Exception类进行描述(例:疾病中可治愈的),对于Exception可以使用针对性的处理方式进行处理
无论Error或者Exception都具有一些共性内容
比如:不正常情况的信息,引发原因等
Java提供了特有的语句进行处理
try{
需要被检测的代码
}catch(异常类 变量){
处理异常的代码(处理方式)
}finally{
一定会执行的语句
}
public String getMessage() //获取异常的信息
public String toString() //异常名称:异常信息
public void printStackTrace()打印异常的堆栈的跟踪信息;异常名称,异常信息,异常出现的位置(其实jvm默认的异常处理机制,就是在调用printStackTrace方法.)
1. 声明异常时,建议声明更为具体的异常,这样处理可以更具体(声明的具体,处理就会具体)
2. 出现程序以外的异常,程序应该停掉,而不是通过Exception(最大的异常处理掉),而且如果catch获取异常为Exception为第一个,其他的异常就都失效了,而且放在Exception下面会报错
3. 对方声明几个异常,就对应有几个catch块,不要定义多余的catch块
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面
建议:在进行catch处理时,catch中一定要定义具体处理方式.不要简单定义一句e.printStackTrace(),也不要简单的就书写一条输出语句
因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象.所以对于这些特有的问题可以按照java对问题封装的思想.将特有的问题进行自定义的异常封装
需求,在本程序中,对于除数是-1,也视为是错误的是无法进行运算的,那么就需要对这个问题进行自定义的描述
自定义异常继承Exception,因为是自定义的,jvm不认识,所以不能自动抛出,只能手动抛出
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作.
要么在内部try catch处理.
要么在函数上声明,让调用者处理
一般情况下,函数内出现异常,函数上需要声明.
class FuShuExcption extends Exception
{
}
class Demo
{
int div(int a,int b)throws FuShuExcption//当方法内部出现了非RuntimeException的异常,都需要在方法后面进行生命,让调用者处理
{
if(b<0)
throw new FuShuExcption();
return a/b;
}
}
class ExceptionDemo2
{
public static void main(String[] args)
{
Demo d=new Demo();
try{
d.div(4,1);
}catch(FuShuExcption e){
System.out.println("hello");
}
}
}
发现打印的结果中只有异常的名称,却没有异常的信息
hello.FuException
at hello.ZiException.chu(Test.java:22)
at hello.Test.main(Test.java:8)
因为自定义的异常并未定义信息
如何定义异常信息呢??
因为父类中已经把异常信息的操作都完成了
所以子类只要在构造时,将异常信息传递给父类通过super语句
那么就可以直接通过getMessage方法获取自定义的异常
自定义异常:
1. 必须是自定义类继承Exception
继承Exception原因:
异常体系有一个特点:因为异常类和异常对象都被抛出.它们都具备可抛性,这个可抛性是trowable这个体系中独有特点.
只有这个体系中的类和对象才可以被throws和throw操作
1. throws使用在函数上,throw使用在函数内
2. throws后面跟的异常类,可以跟多个,用逗号隔开;throw后面跟的是异常对象
函数内抛要在函数上声明
如果不想使用异常自带的报错信息,可以自己写一个
class Demo
{
int div(int a,int b)
{
if(b==0)
throw new ArithmeticException("除数为零了...");//jdk提供的Exception有一个构造方法可以传递自定义的报错信息
return a/b;
}
}
class ExceptionDemo2
{
public static void main(String[] args)
{
Demo d=new Demo();
int x=d.div(4,0);
System.out.println(x);
}
}
Exception中有一个特殊的子类异常:RuntimeException 即运行时异常
如果在函数内容抛出该异常或其子类,函数上可以不用声明,编译可以通过
class Demo
{
int div(int a,int b)//这里不需要声明
{
if(b==0)
throw new ArithmeticException("除数为零了...");//jdk提供的Exception有一个构造方法可以传递自定义的报错信息
return a/b;
}
}
class ExceptionDemo2
{
public static void main(String[] args)
{
Demo d=new Demo();
int x=d.div(4,0);
System.out.println(x);
}
}
class Demo
{
int div(int a,int b)throws ArithmeticException//此处声明调用者可以不用对异常进行处理
{
return a/b;
}
}
class ExceptionDemo2
{
public static void main(String[] args)
{
Demo d=new Demo();
int x=d.div(4,0);//调用方法不需要对异常进行处理
System.out.println(x);
}
}
之所以不用再函数上声明,是因为不需要让调用者处理.当该异常发生,希望程序停止.因为在运行时,出现了无法继续运算的情况,希望停止程序后,由程序员对代码进行修正.
自定义异常时:如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException.
对于异常,分为两种:
1. 编译时被检测的异常
Javac在编译时,会检测方法,如果这个方法抛出了非RuntimeException异常或者其子类,如果函数上没有标明异常,就会认为这是有安全隐患的.而且调用者也要对异常进行处理(要么抛,要么try)
2. 编译时不被检测时的异常(运行时异常.RuntimeException及其子类)
毕老师用电脑上课.(名词提炼法)
异常:
1. 电脑蓝屏了
2. 电脑冒烟了
要对问题进行描述,封装成对象.
1. 蓝屏时,可以处理,所以要表示出去
可是当冒烟发生后,出现讲课进度无法继续
出现了讲师的问题:课时计划无法完成
在找领导解决事情的时候,可以让学员做练习
class ExceptionTest
{
public static void main(String[] args){
Teacher t=new Teacher("李老师",new Computer());
try
{
t.jiangKe();
}
catch (NoPlanException e)
{
System.out.println(e.toString());
System.out.println("换老师,换电脑");
}
}
}
class Teacher
{
private String name;
private Computer pc;
public Teacher(String name){
this.name=name;
}
public Teacher(String name,Computer pc){
this(name);
this.pc=pc;
}
public void jiangKe()throws NoPlanException{
try{
pc.run();
System.out.println("讲课");
}catch(LanPingException e){
pc.reset();
}
catch(MaoYanException e){
test();//抛出异常,程序结束,此句话执行不到
throw new NoPlanException("课时无法继续"+e.getMessage());//不能讲课有一个理由,即报的异常
}
}
public void test(){
System.out.println("练习");
}
}
class Computer
{
private int state=3;
public void run()throws LanPingException,MaoYanException{
if(state==2)
throw new LanPingException("电脑蓝屏了...");
if(state==3)
throw new MaoYanException("冒烟了...");
System.out.println("电脑运行");
}
public void reset(){
state=1;
System.out.println("电脑重启了...");
}
}
class LanPingException extends Exception
{
LanPingException(String mess){
super(mess);
}
}
class MaoYanException extends Exception
{
MaoYanException(String mess){
super(mess);
}
}
class NoPlanException extends Exception
{
NoPlanException(String msg){
super(msg);
}
}
finally中存放的是一定会被执行的代码
应用:关闭资源
当catch中有return时,程序将跳出,这时,将不会执行try catch外的其他代码,但会执行finally中的代码
class FinallyDemo
{
public static void main(String[] args){
int x=0;
DoChu d=new DoChu();
try
{
x=d.chu(4,-5);
System.out.println("x="+x);
}
catch (SuanFaException e)
{
e.toString();
return ;
}finally{
System.out.println("finally");
}
System.out.println("over");
}
}
class SuanFaException extends Exception
{
SuanFaException(String msg){
super(msg);
}
}
class DoChu
{
public int chu(int a,int b)throws SuanFaException{
if(b<0)
throw new SuanFaException("除数不能为负");
return a/b;
}
}
try{ //这样编译是可以通过的,因为异常在内部被解决了
throw new Exception();
}catch(Exception e){
}
try{
throw new Exception();
}catch(Exception e){
throw e; //这样是不能编译通过的,因为处理了一个异常,又抛出了新的异常
}
try{
throw new Exception();
}catch(Exception e){
try{
throw e; //这样就可以编译通过,因为程序又在内部解决了异常
}catch(){
}
}
用法:可能会产生一些问题,但是这些问题不会再这个方法中处理.但是最后要关闭资源
try{
throw new Exception();
}finally{
//这样编译不能通过,因为程序没有处理异常
}
记住:catch是用于处理异常的,如果没有catch就代表异常没有被处理过,如果该异常是检测时异常.就必须声明
1. 子类覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或该异常的子类(你只能是父类的相同问题,或是比父类更小的问题 ),如果子类重写的方法真的要抛出不是父类的异常,就得使用try---catch
早期的程序不能处理后期的新程序,
2. 如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集
3. 如果父类或者方法的接口中没有异常抛出,那么子类在覆盖方法时也不可以抛出异常;如果子类方法发生了异常.就必须要进行try处理.绝对不能抛
有个圆形和长方形
都可以获取面积
对于面积如果出现非法的数值,视为是获取面积时出现的问题.
问题通过异常来表示.
先要对这个程序进行基本的设计
当值出现非法时,应该把程序直接停掉,因为下面的内容再执行是没有意义的
分析:
遇到问题,把对象封装起来,万物皆对象
抛异常可以抛更大的,但是不便于查看是哪的问题class AreaTest
{
public static void main(String[] args){
Chang c=new Chang(-12.1,12.3);
c.getArea();
}
}
interface DoArea
{
void getArea();
}
class Chang implements DoArea
{
private double wid;
private double hei;
Chang(double wid,double hei)// throws FuShuException
{
if(wid<0 || hei<0)
throw new FuShuException("长方形的长和宽都不能为负数");
this.wid=wid;
this.hei=hei;
}
public void getArea(){
System.out.println( wid*hei);
}
}
class Yuan implements DoArea
{
private static final double PI=3.14;
private double r;
Yuan(double r){
this.r=r;
}
public void getArea(){
System.out.println(PI*r*r);
}
}
class FuShuException extends RuntimeException
{
FuShuException(String msg){
super(msg);
}
}