异常知识点

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

1、异常基本概念

异常:就是程序在运行时出现不正常情况。
异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。其实就是java对不正常情况进行描述后的对象体现。
对于问题的划分:

两种:一种是严重的问题,一种非严重的问题。
对于严重的,java通过Error类进行描述。对于Error一般不编写针对性的代码对其进行处理。
对于非严重的,java通过Exception类进行描述。对于Exception可以使用针对性的处理方式进行处理。

2、java异常的处理

java 提供了特有的语句进行处理。
try
{
    需要被检测的代码;
}
catch(异常类 变量)
{
    处理异常的代码;(处理方式)
}
finally
{
    一定会执行的语句;
}

//示例
class Demo
{
	int div(int a,int b)throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现问题。
	{                                 //这样的话,如果调用这个方法者不处理,编译时就会出现异常
		return a/b;
	}
}
class  ExceptionDemo
{
	public static void main(String[] args)//当然我也可以在这边将异常再次抛出,就能正常编译了
	{                                      //但是若调用方法时传入了会产生异常的参数,编译正常,但是运行会异常
		                                 //因为将异常抛给虚拟机了
		Demo d = new Demo();
		try
		{
			int x = d.div(4,1);
			System.out.println("x="+x);//注意打印语句如果放在try外面,它就不知道x是谁了
			                   //而且要知道,当异常发生在上面一句时,这句就不会运行了
		}
		catch (Exception e)//Exception e = new ArithmeticException(); 这个异常是除数为零异常
		{
			System.out.println("除零啦");
			System.out.println(e.getMessage());//  / by zero; 这就是获取的异常信息
			System.out.println(e.toString());// 异常名称 : 异常信息。 打印的比上一句更全面

			e.printStackTrace();//打印异常名称,异常信息,异常出现的位置。 内容最具体
							           //其实jvm默认的异常处理机制,就是在调用printStackTrace方法。
		}		
		System.out.println("over");//异常处理完成后,这句就可以运行了

	}
}

3、对多异常的处理

(1)声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
(2)对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。 如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。

建立在进行catch处理时,catch中一定要定义具体处理方式。不要简单定义一句 e.printStackTrace(),也不要简单的就书写一条输出语句。通常呢,会用日志的形式记录下来,作为异常日志

//这得要一个例子,还是上面那块代码,修改了下,注意看注释理解上文
class Demo
{
	int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException//在功能上通过throws的关键字声明了该功能有可能会出现问题。
	{

		int[] arr = new int[a]; //而正常情况下,若是一旦这句异常了后面一句就不会执行了,直接输出这句的异常
		System.out.println(arr[4]);
		return a/b;
	}
}
class  ExceptionDemo
{
	public static void main(String[] args)
	{
		Demo d = new Demo();
		try
		{
			int x = d.div(5,0); //输入这个参数会有两个异常
			System.out.println("x="+x);
		}
		catch(Exception e) //但是这个是异常的老大,放在最前面的话,就会都被它处理掉了,所以这样写,是有问题的
		{                //而且,尽量不要用这种大包大揽的异常类,没有针对性,自己没发现的异常也会就这样被他处理了
			System.out.println("hahah:"+e.toString());
		}
		catch (ArithmeticException e)
		{
			System.out.println(e.toString());//这个toString方法其实自动调用getMessage方法
			System.out.println("被零除了!!");

		}
		catch (ArrayIndexOutOfBoundsException e)
		{
			System.out.println(e.toString());
			System.out.println("角标越界啦!!");
		}
		System.out.println("over");
	}
}

4、自定义异常(很有意思得多看看)仔细看注释

/*
需求:在本程序中,对于除数是-1,也视为是错误的是无法进行运算的。
那么就需要对这个问题进行自定义的描述。
*/
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关键字抛出一个自定义异常对象。
      /*                                                                                     //注意看给这个异常对象传的参数
      当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。要么在内部try catch处理。
      要么在函数上声明让调用者处理。这边在函数上面声明了
      */
		return a/b;
	}
}
class  ExceptionDemo
{
	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());//其实是调用getMessage方法
			System.out.println("错误的负数是:"+e.getValue());
		}
		System.out.println("over");
	}
}

5、throws和throw的区别

(1)throws使用在函数上。throw使用在函数内。
(2)throws后面跟的异常类。可以跟多个。用逗号隔开。throw后跟的是异常对象。

6、RuntimeException

Exceptoin中有一个特殊的子类异常RuntimeException 运行时异常。
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过;

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

总结异常分两种:
(1)编译时被检测的异常。
(2)编译时不被检测的异常(运行时异常。RuntimeException以及其子类)

7、finally

//这段代码反应了finally的作用
class FuShuException extends Exception//这个异常在函数中被扔出时是要在函数上声明的
{
	FuShuException(String msg)
	{
		super(msg);
	}
}

class Demo
{
	int div(int a,int b)throws FuShuException//表明这个异常还是可处理的
	{
		if(b<0)
			throw new FuShuException("除数为负数");
		return a/b;
	}
}
class  ExceptionDemo
{
	public static void main(String[] args) 
	{
		Demo d = new Demo();
		try
		{
			int x = d.div(4,-1);//发生异常
			System.out.println("x="+x);
		}
		catch (FuShuException e)
		{
			System.out.println(e.toString());
			return;//表示退出主函数,但是finally中的代码还是会执行,over就打印不出来了。
			//System.exit(0);//系统,退出。jvm结束。只有这种情况下读不到finally
		}
		finally
		{
			System.out.println("finally");//finally中存放的是一定会被执行的代码。
		}
		System.out.println("over");
	}
}

那,关于finally通常用于的地方呢,下段伪代码可以展示
总结:finally代码块:定义一定执行的代码。通常用于关闭资源。这个代码反应的思想很重要,是一种模块化的思想,模块间抛异常,要抛对方能够处理的异常

class NoException extends Exception//定义没有数据异常
{
}
public void method()throws NoException
{
	try
	{		
		连接数据库;
		数据操作;//throw new SQLException();
	}
	catch (SQLException e)
	{
		会对数据库进行异常处理;
		//像这种问题是有关联性的,我自己处理了,还要让别人知道因此还得再抛一个异常
		throw new NoException();//不能抛sql异常,这个提供数据者无关系,因此我们要抛对方能处理的异常
	}
	finally
	{
		关闭数据库;//该动作,无论数据操作是否成功,一定要关闭资源。
	}
}
最后记住一点:catch是用于处理异常。如果没有catch就代表异常没有被处理过,如果该异常是检测时异常。那么必须声明。

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

(1)子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类
(2)如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
(3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
     总之:这种情况下如果子类方法发生了异常。就必须要进行try处理。绝对不能抛。

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值