异常

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

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

无论error或者exception都具有一些共性内容;
比如:不正常情况的信息,引发原因等;
Throwable
   ---Error
   ---Exception

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

有三个结合格式:

        (1)try

             {

             }

             catch ()   当没有必要资源需要释放时,可以不用定义finally。

             {

             }

        (2)try

             {

             }

             finally  异常无法直接catch处理,但是资源需要关闭。

             {

             }

        (3)try

             {

             }

             catch ()

             {

             }

             finally

             {

             }

异常处理的三种格式;
try和fianlly可以在一起,处理的问题可以抛给下一个调用者,不一定非要处理;但要把必须执行的代码放在finally中即可;
记住:catch是用于处理异常。如果没有catch就代表没有被处理过,如果该异常时检测时异常,那么必须声明。

5.对捕获到的异常对象进行常见方法操作。
String getMessage():获取异常信息;

在函数上声明异常。便于提高安全性,让调用的进行处理。不处理编译失败;

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

建议在进行catch处理时,catch中一定要定义具体的处理方式。
不要简单定义一句e.printStackTrace();也不要简单的就书写一条输出语句;

举例:

package day03;
class Demo
{
	//在功能上通过throws的关键字声明了该功能有可能会出现问题;
int div(int a,int b)throws Exception
{
	//java虚拟机识别问题,然后把问题封装成对象new AritchmeticException()
	return a/b;
}
}

public class ExceptionDemo {
	public static void main(String[] args) {
		Demo d = new Demo();
		int x;
		try {
			/*虚拟机把问题对象抛给调用这个功能的对象new AritchmeticException(),try尝试检测,
			检测到这个问题对象,把它丢给catch()如果没有try,没有检测到,主函数没办法处理问题,
			 虚拟机就会调用默认的处理方法,导致主函数停止。
*/			x = d.div(1, 0);
			System.out.println(x);//这句没有执行
		} catch (Exception e) {//Exception e=new AritchmeticException();catch接受到对象就处理了;
			
			System.out.print(e.toString());
		}
	}

}


7自定义异常
(1).因为项目中会出现特有的问题,这些问题并未被java所描述并封装对象,所以对于这些特有的问题可以按照java的对问题封装的思想,将特有的问题,进行自定义的异常封装;

需求:在本程序中,对于除数是负数,也视为是错误的,是无法进行运算的,那么就需要对这个问题进行自定义的描述;

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

一般情况下,函数内出现异常,函数上需要声明;

发现打印的结果中只有异常的名称,却没有异常的信息。
因为自定义的异常并未定义所属信息。

如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了。
所以子烈只要在构造函数时,将异常信息传递给父类通过super语句。
那么就可以直接通过getMessage方法获取自定义的异常信息;

自定义异常:
必须是自定义类继承Exception。

继承Exception原因:
 异常体系有一个特点:因为异常类和异常对象都需要被抛出。
他们都具备可抛性。这个可抛性是Throwable这个体系中独有特点。

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

package day03;

class FuShuException extends Exception
{
private int value;

FuShuException(String msg,int value)
{
super(msg);
this.value = value;
}

public int getValue()
{
return value;
}
}

class Demo3
{
int div(int a,int b) throws FuShuException
{
if(b<0)
//手动通过throw关键字抛出一个自定义异常;
   throw new FuShuException("出现了除数是负数的情况/by fushu",b);
return a/b;
}
}

public class ExceptionDemo3
{
public static void main(String[] args)
{
Demo3 d = new Demo3();
try
{
int x= d.div(4,-1);
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");
}
}

8.异常覆盖:
异常在子类覆盖中的体现:
子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类;

package day03;

class AException extends Exception
{

}
class BException extends AException
{

}
class CException extends Exception
{

}
/*Exception
    |--AException
       |--BException
    |--CException
*/
class Fu
{
void show() throws AException
{

}
}

class Test
{
void function(Fu f)
{
try
{
f.show();//调用一个抛出异常的方法,要么抛要么try
}
catch(AException e){//早期的程序不能处理后期出现的异常。

}
}
}

class Zi extends Fu
{
//如果父类抛出AException,子类只能抛出AException和它的子类,如果在子类中出现新的异常CException,不能抛,只能try;
void show() throws BException
{

}
}

public class  ExceptionDemo4
{
public static void main(String[] args)
{
	Test t = new Test();
//t.function(new Fu());
t.function(new Zi());
}
}

9.小练习1

package day03;

import java.awt.peer.SystemTrayPeer;

/*
 * 需求:
 * 分析:
 * 毕老师用电脑上课。
 问题领域中涉及两个对象。
 毕老师,电脑。
 分 析其中的问题。
 比如电脑蓝屏啦。冒烟啦。
 * 

 */

//电脑蓝屏自定义异常
class BlueScreenException extends Exception {
	BlueScreenException(String msg) {
		super(msg);

	}
}

// 电脑自定义冒烟了异常
class FireBreakingException extends Exception {
	public FireBreakingException(String msg) {
		super(msg);
	}
}

// 老是不能讲课,生病了异常
class NoPlanException extends Exception {
	public NoPlanException(String msg) {
		super(msg);
	}
}

class Computer {
	private int start =2;
	public void  Setstart(int start){
		this.start=start;
	}

	// 电脑运行
	void run() throws FireBreakingException, BlueScreenException {
		if (start == 1)
			throw new BlueScreenException("电脑蓝屏了 哈哈哈");
		if (start == 2)
			throw new FireBreakingException("电脑冒烟了");
		System.out.println("电脑运行");
	}

	void reset() {
		start = 0;
		System.out.println("电脑退出");
	}
}

// 描述老师
class Teacher {
private String name;
private Computer comp;
public Teacher(String name) {
this.name=name;
comp = new Computer();
}
//老师讲课
void teach() throws NoPlanException 
{
try {
	comp.run();
} catch (FireBreakingException e) {
	System.out.println(e.toString());

	test();
	throw new NoPlanException(" 课程进度不能完成,因为"+e.toString());
	
} catch (BlueScreenException e) {
	System.out.println(e.toString());
	comp.reset();
	teach();
	
	
	
}	
}
public void test()
{
System.out.println("大家练习");	
}
	
}

public class ExceptionDemo5 {

	public static void main(String[] args) {
		Teacher t = new Teacher("毕老师");
		
		
		try {
			t.teach();
		} catch (NoPlanException e) {
			System.out.println(e.toString());
			System.out.println("换下一个老师");
		}

	}

}

运行结果:

day03.FireBreakingException: 电脑冒烟了
大家练习
day03.NoPlanException:  课程进度不能完成,因为day03.FireBreakingException: 电脑冒烟了
换下一个老师

 练习2

package day03;

/*需求:有一个圆形和长方形。都可以获取面积。对于面积如果出现非法的数值,视为获取面积出现问题。问题通过异常来表示。
*/
class No extends RuntimeException
{

 No(String msg) {
	super(msg);
}
}
//把面积设计成扩展功能;定义成接口;
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 No("出现非法值");
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)//throws  NoValueException
{
if(radius <=0)
throw new No("非法");
this.radius =radius;

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




public class  ExceptionDemo6 
{
public static void main(String[] args)
{

//当数值不为负数时了正常运行出结果,当为负数是,因为是runtimeException异常,所以程序直接停掉,
	Rec r = new Rec(-2,4);
	r.getArea();
	Circle c = new Circle(-5);
	c.getArea();
	System.out.println("over");





}
}

运行结果:

10.throw和throws的区别;
throws使用函数上;
throw使用在函数内

throws后面跟的是异常类,可以跟多个,用逗号隔开。
throw后面跟的是异常对象。

特殊:runtimeException异常
Exception中有一个特殊的子类异常RuntimeException

如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过;之所以不用在函数上声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。

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

异常的分类:
1,编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。
这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。
这样的问题都可以针对性的处理。
2,编译时不检测异常(运行时异常):就是Exception中的RuntimeException和其子类。
这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者的原因导致的而或者引发了内部状态的改变导致的。
那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行修正。
所以自定义异常时,要么继承Exception,要么继承RuntimeException。

举例:

1.

package day03;

class Person
{
public void CheckName(String name)
{
if(name.equals("lisi"))//改成下面的程序就不会停止
//if("lisi".equals(name))//或者if(name!=null&&name.equals("lisi")
System.out.println("yes");
else
System.out.println("no");
}
}

public class ExceptionDemo7
{
public static void main(String[] a)
{
Person p = new Person();
p.CheckName(null);//传一个null值
}
}


2.

package day03;

//RuntimeException的出现引发程序停止;
class FuShuException1 extends RuntimeException
{
FuShuException1(String msg)
{
super(msg);
}
}

class Demo8
{
int div(int a,int b)
{
if(b<0)
throw new FuShuException1("出现除数是负数了");
if(b==0)
throw new ArithmeticException("被零除了");
return a/b;
}
}

class A
{
public static void main(String[] a)
{
Demo8 d = new Demo8();
int x=d.div(4,-1);
System.out.println("x="+x);
System.out.println("over");

}
}

11.异常总结
异常时什么?是对问题的描述。将问题进行对象的封装。

异常体系:
throwable
    |--Error
    |--Exception
        |--RuntimeException
异常体系的特点:异常体系中的所有类以及建立的对象都具备可抛性。也就是说可以被throw和throws关键字所操作。只有异常体系具备这个特点。

当函数内部有throw抛出异常对象,并未进行try处理。必须要在函数上声明,否则,会在编译失败;
注意:RuntimeException除外,也就是说,函数内如果抛RuntimeException异常,函数上可以不声明;

如果函数声明了异常,调用者需要进行处理,处理方法可以throws可以try;

异常有两种:
  编译时被检测异常
     该异常在编译时,如果没有处理(没有抛也没有try),编译失败;该异常被标识,代表这可以被处理;
  运行时异常(编译时不检测)
      在编译时,不需要处理,编译器不检查;
      该异常的发生,建议不处理,让程序停止,需要对代码修正;

注意:
(1).fianlly中定义的通常是关闭资源代码。因为资源必须释放;
(2).finally只有一种情况不会执行。当执行到System.exit(0);finally不会执行;


自定义异常:
定义类继承Exception或者RuntimeException
1.为了让自定义类具备可抛性;
2.让该类具备操作异常的共性方法;

当要定义自定义异常的信息时,可以使用父类已经定义好的功能。
异常信息传递给父类的构造函数。
class MyException extends Exception
{
MyException(String message)
{
super(message);
}
}

自定义异常:按照java的面向对象思想,将程序出现的特有问题进行封装;

异常好处:
   1.将问题进行封装;
   2.将正常流程代码和问题处理代码相分离,方便阅读;

异常的处理原则:
   1.处理方式有两种:try或者throws。
   2.调用到抛出异常的功能时,抛出几个,就处理几个。
     一个try可以对应多个catch
   3.多个catch,父类的catch放到最下面;
   4.catch内,需要定义针对性的处理方式。不要简单的定义     PrintStackTrace,也不要不写;
     当捕获到的异常,本功能处理不了时,可以继续在catch中抛出;
try
{
throw new AException();

}
catch(AException e)
{
throw e;
}
如果该异常处理不了,但并不属于该功能出现的异常。
可以讲异常转换后,在抛出和该功能相关的异常。

或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,当调用者知道,并处理,也可以将捕获异常处理后,转换新的异常。
try
{
throw new AException();

}
catch(AException e)
{
//对 AException处理;
throw new BException();
}
比如:汇款的例子;

异常的注意事项:
    在子父类覆盖时:
    1.子类抛出的异常必须是父类异常的子类或者子集;
    2.如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛;


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值