java基础--异常机制

一、异常的体系:

   Throwable

         ---Error

         ---Excepeion

       Error: 通常出现重大问题如:运行的类不存在或者内存溢出等。不编写针对代码对其处理

       Exception: 在运行时出现的一些状况,可以通过try catch finally 处理


Error与Exception相同点:

     不正常情况的信息,引发原因等。

     ExceptionError的子类名都是以父类名作为后缀


异常体系的特点:

异常体系中的所有类以及建立的对象都具备可抛性。

也就是说可以被throwthrows关键字所操作。

只有异常体系具备这个特点。


Throwable中的方法

        getMessage():获取异常信息,返回字符串

        toString():获取异常类名和异常信息,返回字符串

        printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置,返回void

        printStackTracePrintStream s):通常用该方法将异常内容保存在日志文件中,以便查


二、异常分两种:


      1、编译时被检测的异常

            需要进行处理,即try或者throw,否则编译失败

            该异常被throws标识,代表可以被处理

      2、运行时异常(RuntimeException以及其子类)

           编译时,不需要处理,编译器不检查

          该异常的发生,建议不处理,让程序停止,需要对代码进行修正



三、throws 和 throw


作用:      

 throws 用于标识函数暴露出的异常。

       throw 用于抛出异常对象


区别:

     throws 用在函数上,后面跟异常类名。

    throw用在函数内,后面跟异常对象。


四、异常处理


      当函数内容有throw抛出异常对象,并未进行try-catch处理,必须要在函数上声明,否则编译失败。

      注意:

         RuntimeException除外,也就说,函数内如果抛出的RuntimeExcpetion异常,函数上可以不用声明。

	try{
            需要检测的代码
	}catch(异常类 变量){
	    处理的代码
	}finally{
	    一定会执行的代码
	}


finally注意事项:

1finally中定义的通常是 关闭资源代码。因为资源必须释放。

2finally只有一种情况不会执行。当执行到System.exit(0); (虚拟机退出),fianlly不会执行。


3种处理的结合方式:

try-catch try-finallytry-catch-finally

记住一点:catch是用于处理异常,如果没有catch,就代表异常没有被处理过,如果该异常是检测时异常,那么必须声明。


异常处理原则:

    1当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作,要么在内部try-catch,要么在函数上声明让调用者处理

    2、声明异常时,建议声明更为具体的异常,这样处理的可以更具体

    3、对方声明几个异常,就对应几个catch块,不要定义多余的catch

          如果多个catch块中的异常时继承的关系,父类异常应该放在最下面。(如果父类放上面,则子类异常就执行不到了)

    4、建议在catch处理时,catch中一定要定义具体的处理方式,便于查错。

        当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。

	try{
		throw new AException();
	}
	catch (AException e){
		throw e;
	}

     5如果该异常处理不了,但并不属于该功能出现的异常。可以将异常转换后,在抛出和该功能相关的异常。

           或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,让调用者知道出现了异常,并处理。

           也可以将捕获异常处理后,转换新的异常。

	try{
		throw new AException();
	}
	catch (AException e){
		// 对AException处理。
		throw new BException();
	}



五、自定义异常

  

   1、由来:

         因为项目中会出现特有的问题,而这些问题并未被java所描述并封装成对象,所以对 于这些特有的问题可以按照java的对问题封装的思想,

     将特有的问题,进行自定义的 异常封装。


  2、自定义异常好处:

      按照java的面向对象思想,将程序中出现的特有问题进行封装。


  3、自定义异常需要继承Exception或者RuntimeException

  原因:

      1> 异常体系有一个特点:因为异常类和异常对象都被抛出,他们都具备可抛性,而这个可抛性是Throwable这个体系中独有特点,

          只有这个体系中的类和对象才可以被throwsthrow操作。

      2>让该类具备操作异常的共性方法


  4如何定义异常信息呢?

     因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,将异常信息传递 给父类通过super语句。那么就可以直接通过

     getMessage方法获取自定义的异常信息。


示例:

    这里假不允许输入负数

    我们可以在自定义异常获取更多的信息,方法同样是通过构造函数传入


	class FuShuException extends Exception //getMessage();{
		private int value;
	
		FuShuException(){
			super();
		}
		FuShuException(String msg,int value){
			super(msg);
			this.value = value;
		}
	
		public int getValue()
		{
			return value;
		}
	
	}
	
	class Demo{
		int div(int a,int b)throws FuShuException{
			if(b<0)
				throw new FuShuException("出现了除数是负数的情况------ / by fushu",b);//手动通过throw关键字抛出一个自定义异常对象。
			return a/b;
		}
	}

	class  ExceptionDemo3{
		public static void main(String[] args) {
			Demo d = new Demo();
			try{
				int x = d.div(4,-9);
				System.out.println("x="+x);		
			}
			catch (FuShuException e){
				System.out.println(e.toString());
				//System.out.println("除数出现负数了");
				System.out.println("错误的负数是:"+e.getValue());
			}
			System.out.println("over");
		}
	}


五、RuntimeException:

     Exception中有一个特殊的子类异常:RuntimeException运行时异常。

    

   1、RuntimeException不用声明的情况:

         如果在函数内部抛出该异常或其子类,函数上可以不用声明,编译一样通过

         如果在函数上声明了该异常或其子类,调用者可以不用声明,编译一样通过

    

    2、不用在函数声明的原因:

         不希望让调用者处理,当该异常发生,希望程序停止。因为在运行时,出现了无法继续 运算的情况,希望调用者停止程序后,对代码进行修正。


自定义异常时,如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException



六、异常在子父类覆盖中的体现;


      1,子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父    类的异常或者该异常的子类。

      2,如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子类 或者子集。

      3,如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出    异常。如果子类方法发生了异常。就必须要进行try处理。绝对不能抛。



七、练习:


练习一


需求:

     1、对于老师用电脑上课中出现的问题进行处理

     2、讲课中出现的问题:电脑蓝屏、电脑冒烟

     3、可是当冒烟发生后,出现讲课进度无法继续

           出现了讲师的问题:课时计划无法完成。

     4、要对问题进行描述,封装成对象。


//蓝屏异常
class LanPingException extends Exception{
	LanPingException(String message){
		super(message);
	}
}

//冒烟异常
class MaoYanException extends Exception{
	MaoYanException(String message){
		super(message);
	}
}

//计划外异常
class NoPlanException extends Exception{
	NoPlanException(String msg){
		super(msg);
	}
}

//计算机类
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 Teacher{
	private String name;
	private Computer cmpt;

	Teacher(String name){
		this.name = name;
		cmpt = new Computer();

	}

	//讲课的过程,对于自己可以处理的就处理,不可处理的抛出
	public void prelect()throws NoPlanException{
		try{
			cmpt.run();			
		}
		catch (LanPingException e){
			cmpt.reset();	//电脑蓝屏,自己可以处理,重启即可
		}
		catch (MaoYanException e){
			//让同学先做练习
			test();

			//电脑冒烟,自己无法处理,将异常转换为其他异常抛出
			throw new NoPlanException("课时无法继续"+e.getMessage());
			
		}
		System.out.println("讲课");
	}

	//在处理冒烟问题之前,先做其处理,让同学做练习
	public void test(){
		System.out.println("练习");
	}

}


class ExceptionTest {
	public static void main(String[] args) {
		Teacher t = new Teacher("毕老师");
		try{
			t.prelect();
		}
		catch (NoPlanException e){
			System.out.println(e.toString());
			System.out.println("换老师或者放假");
		}
		
	}
}

练习


需求:

      1、有一个圆形和长方形,都可以获取面积。

      2、对于面积如果出现非法的数值,视为是获取面积出现问题。

      3、问题通过异常来表示,对这个程序进行基本设计。


示例说明:

      对于面积的求取,主要是输入数据的异常,所以这里定义了一个非法数据异常,

      当出现非法数字时,程序不需要再进行下去,所以这里继承了RuntimeException,不需声明

      对于一些经常用到的常量,我们可以定义为public static final 类型,共享一份,不可修改


class NoValueException extends RuntimeException{
	NoValueException(String message){
		super(message);
	}
}

interface Shape{
	void getArea();
}

class Rec implements Shape{
	private int len,wid;

	Rec(int len ,int wid){		//throws NoValueException
		if(len<=0 || wid<=0)
			throw new NoValueException("出现非法值");

		this.len = len;
		this.wid = wid;
	}

	public void getArea(){
		System.out.println(len*wid);
	}
}

class Circle implements Shape{
	private int radius;
	public static final double PI = 3.14;

	Circle(int radius){
		if(radius<=0)
			throw new NoValueException("非法");
		this.radius = radius;
	}

	public void getArea(){
		System.out.println(radius*radius*PI);
	}
}

class  ExceptionTest1{
	public static void main(String[] args) {	
		
		Rec r = new Rec(3,4);
		r.getArea();

		Circle c = new Circle(-8);

		System.out.println("over");
	
	}
}


posted @ 2012-12-06 20:34  积小流,成江海  阅读(206)  评论(0编辑  收藏  举报