面向对象之异常

-------android培训java培训、期待与您交流! ---------- 
 
异常:就是程序在运行时出现不正常情况。
 比如说访问一个长度为3的数组中的第4个元素就会抛出角标越界异常。
 
java语言中的异常是通过一个对象来表示的,程序运行时抛出的异常,实际上就是一个异常对象。这个对象中封装了错误信息,还提供了一些处理方法,如getMessage()方法获取异常信息。
 
异常有的需要进行捕获处理或声明抛出,这种异常称为受检查异常。
而有的是有java虚拟机自动进行捕获处理,这种异常称为运行时异常。
 
异常的划分:
     对于问题的划分:两种:一种是严重的问题,一种是非严重的问题。
     对于严重的,java通过Error类进行描述。 对于Error一般不编写针对性的代码对其进行处理。
     对于非严重的,java通过Exception类进行描述。 对于Exception可以使用针对性的处理方式进行处理。
 
 无论Error或者Exception都具备一些共性内容,比如:不正常情况信息,引发原因等。
 
Exception类又可以分为两种异常类型:
    1,RuntimeException异常。
    2,检查异常。
 
RuntimeException是运行时异常,是程序员编写的程序中的错误导致的。它必须使用异常处理机制来处理,这类异常
在编译时是可以通过的,只是在运行时有java虚拟机来抛出。
常见的RuntimeException异常有:算术异常ArithmeticException,空指针异常NullPointerException,
角标越界异常IndexOutOfBoundsException,类型转换异常ClassCastException等等。
 
对于检查异常必须通过try...catch捕获或由throws抛出,否则编译出错。
常见的检查异常有:未找到相应类异常ClassNotFoundException,输入输出异常IOException,
文件未找到异常FileNotFoundException,访问被拒绝时抛出的异常IllegalAccessException 等等。
 
 2,异常的处理
异常产生后,若不做任何处理,则程序就会被终止,为了保证程序有效的执行,就需要对产生的异常进行相应处理。
异常有两种处理方式:
    1,在当前方法中进行捕获然后处理异常。这里要用到try,catch,finally三个关键字。
    2,通过throw和throws将异常向上抛出,由方法的调用者来处理。
 
 使用try...catch语句:
  try  {
      需要被检测的代码
  }  catch(异常类 异常对象)  {
      处理异常的代码;(处理方式)
  } finally  {
      一定会执行的语句;
  }
  记住:catch是用来处理异常的,如果没有catch就代表异常没有被处理过,如果该异常是检测时异常那么必须声明catch。
    try语句块中的代码可能同时存在多种异常,那么到底捕获的是哪一种类型的异常,是由catch语句中的“异常类”参数来指定的。
    catch语句类似于方法的声明,包括一个异常类型和该类的一个对象:
         异常类:必须是Throwable类的子类,用来指定了catch语句要捕获的异常。
         异常类对象:可以在catch语句块中被调用,例如调用对象的getMessage()方法获取对异常的描述信息。
比如声明一个方法将a/b,如果b=0的话,这个方法就会抛出ArithmeticException异常。所以在应用这个方法时就可以通过try...catch语句来捕获该异常,从而进行相应的异常处理。
代码演示:
class Demo
{
	int div(int a,int b)throws Exception 
	{
		return a/b;
	}
}
 class ExceptionDemo
 {
	public static void main(String[] args) 
	{
		Demo d=new Demo();	
		try{
			int x=d.div(9,0);  //抛出ArithmeticException异常
			System.out.println("x="+x);
		}catch(Exception e){//捕获ArithmeticException异常
			System.out.print("被除数为零    ");
			System.out.print(e.getMessage()); 
		}		
		System.out.println("Over");
	}
}
 
对捕获到的异常对象进行常见方法操作。
     String getMessage(); 获取异常信息。
   toString();获取异常类名和异常信息,返回字符串。
 
在try…catch语句中,可以同时存在多个catch语句块。
  一般格式为:try{
                              可能产生异常的代码
                       }catch(异常类1 异常对象){
                              异常1处理代码
                       }catch(异常类2 异常对象){
                              异常2处理代码
                       }

代码中的每个catch语句块都用来捕获一种类型的异常。若try语句块中的代码发生异常,则会由上而下依次来查找能够捕获该异常的catch语句块,并执行该catch语句块中的代码。
对多异常的处理:
   1,声明异常时,建议声明更为具体的异常,这样可以处理的更具体。如:数学异常用ArithmeticException。
         每个异常之间用逗号隔开即可,如:Throws ArithmeticException,ArithmeticException。
   2,对方有几个异常就用几个 catch块,不要定义多余的catch块。
       如果多个catch块中的异常出现继承关系,父类异常catch块放在下面。
例如:
try{
	int x=d.div(9,0);  //抛出ArithmeticException异常
	System.out.println("x="+x);
}catch(ArithmeticException e){ //捕获异常类Exception的子类异常
	System.out.print(e.getMessage()); 
}catch(Exception e){  //捕获ArithmeticException异常
	System.out.print(e.getMessage()); 			
}
 
建议在进行catch处理时,catch中一定要定义具体的处理方式,不要简单的定义一句e.printStackTrace(),
也不要简单的就书写一条输出语句。
 
异常-finally
finally子句需要与try…catch语句一同使用,不管程序中有无异常发生,并且不管之前的try…catch是否顺利执行完毕,最终都会执行finally语句块中的代码,这使得一些不管在任何情况下都必须执行的步骤被执行。
例如:
try{
	int x=d.div(9,0);  //抛出ArithmeticException异常
	System.out.println("x="+x);
}catch(Exception e){  //捕获ArithmeticException异常
	System.out.print(e.getMessage()); 			
}finally{ //不管程序有无异常该语句都会执行
	System.out.println("运算结束");
}

当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作,要么在内部try catch处理,要么在
 函数上声明让调用者处理。
 一般情况下,函数内部出现异常,函数上需要声明。
 
 如何定义异常信息呢?
    因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时将异常信息传递给父类通过super语句,
 那么就可以直接通过getMessage方法获取自定义的异常信息。
   
使用throws关键字抛出异常:
    如果某个方法可能会发生异常,但不想在当前方法中来处理这个异常,那么可以将该异常抛出,然后在调用该方法的代码中捕获该异常并进行处理。抛出多个异常时用逗号隔开
throws和throw的区别:
    throws使用在函数上,throw使用在函数内。
    throws后面跟的是异常类,可以跟多个,用逗号隔开;throw后跟的是异常对象。
 
  自定义异常:
    必须是自定义类继承Exception。如,
class AException extends Exception{
         AException(String message){
 		super(message);
 	}
}
  继承exception原因:
      异常体系有一个特点,因为异常类和异常对象都需要被抛出,他们都具备可抛性,这个可抛性是Throwable 这个体系中独有特点。只有这个体系中的类和对象才可被throws和throw操作。
 
异常的细节:
     1,RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。
    2,一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。
    3,如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常。
    4,如果被覆盖的方法没有抛出异常,子类也不允许抛出异常。如果子类中真的出现异常,只能在子类方法内进行try处理,绝对不允许throws声明。如果处理不了可以选择抛出运行时异常。
  
自定义异常时:如果该异常的发生无法在继续进行运算,就让自定义异常继承RuntimeException。
自定义异常大体可以分为以下几个步骤:
     1,创建自定义异常类。
     2,在方法中通过throw抛出异常对象。
     3,若在当前抛出异常的方法中处理异常,可使用try…catch语句捕获并处理;否则在方法的声明处通过throws指明要抛出的异常。
     4,在出现异常的方法调用代码中捕获并处理异常。
如果自定义的异常类继承自RuntimeExeption异常类,在步骤 3 中,可以不通过throws指明要抛出的异常。
异常在子父类覆盖中的体现:
1,子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类的异常或者该异常的子类。
如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3,如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
   如果子类方法发生了异常,就比须要进行try处理,绝对不能抛。
class NoOilException extends Exception
{
	NoOilException(String msg)
	{
		super(msg);
	}
}
class FlatTireException extends Exception
{
	FlatTireException(String msg)
	{
		super(msg);
	}
}
class StopPlanException extends Exception
{
	StopPlanException(String msg)
	{
		super(msg);
	}
}
class Car
{
	int state = 3;
	public void run() throws NoOilException, FlatTireException
	{
		if(state==2)
			throw new NoOilException("车子没油了,找地方加油···");
		if(state==3)
			throw new FlatTireException("车子爆胎了");
		System.out.println("汽车启动,旅行中···");
	}
	public void reset()
	{
		System.out.println("重新启动车子,继续旅行···");
	}
}
class Tourism
{
	private Car c = new Car();
	public void travel() throws StopPlanException
	{
		try
		{
			c.run();
		}
		catch(NoOilException e)
		{
			c.reset();
		}
		catch(FlatTireException e)
		{
			throw new StopPlanException("旅游暂时停止"+"  "+e.getMessage());
		}
		
		System.out.println("旅游");
	}
}
public class ExceptionTest 
{
	public static void main(String[] args) 
	{
		Tourism t = new Tourism();
		try
		{
			t.travel();
		}
		catch(StopPlanException e)
		{
			System.out.println(e.toString());
			System.out.println("暂时下车休息,打电话找人修车");
		}
		
	}

}


 
 
--------------------------- ------- android培训 java培训 、期待与您交流! ------------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值