黑马程序员--异常

                                                                                       -----------android培训java培训、java学习型技术博客、期待与您交流!------------

异常

异 常:★★★★

异常:就是不正常。程序在运行时出现的不正常情况。其实就是程序中出现的问题。这个问题按照面向对象思想进行描述,并封装成了对象。因为问题的产生有产生的原因、有问题的名称、有问题的描述等多个属性信息存在。当出现多属性信息最方便的方式就是将这些信息进行封装。异常就是java按照面向对象的思想将问题进行对象封装。这样就方便于操作问题以及处理问题。

 

出现的问题有很多种,比如角标越界,空指针等都是。就对这些问题进行分类。而且这些问题都有共性内容比如:每一个问题都有名称,同时还有问题描述的信息,问题出现的位置,所以可以不断的向上抽取。形成了异常体系。 

 

包:java.lang.Throwable

Throwable可抛出的。 

|--Error错误,一般情况下,不编写针对性的代码进行处理,通常是jvm发生的,需要对程序进行修正。

|--Exception异常,可以有针对性的处理方式

  |--RuntimeEception

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

可抛性体现:可以被throwthrows关键字所操作,只有异常体系具备这个特点。

(无论是错误还是异常,它们都有具体的子类体现每一个问题,它们的子类都有一个共性,就是都以父类名作为子类的后缀名。)

------------------------------------------------------

class  ExceptionDemo{

public static void main(String[] args) {

// byte[] buf = new byte[1024*1024*700];//java.lang.OutOfMemoryError内存溢出错误

}

}

------------------------------------------------------

在开发时,如果定义功能时,发现该功能会出现一些问题,应该将问题在定义功能时标示出来(throws),这样调用者就可以在使用这个功能的时候,预先给出处理方式。

如何标示呢?通过throws关键字完成,格式:throws 异常类名,异常类名...

这样标示后,调用者,在使用该功能时,就必须要处理,否则编译失败。

 

处理方式有两种:1、捕捉;2、抛出。

1.对于捕捉:java有针对性的语句块进行处理。

try {

需要被检测的代码;

}

catch(异常类 变量名){

异常处理代码;

}

fianlly{

一定会执行的代码;

}

2.问题没处理或者处理不了----抛出

      public class void main(String[] args) throws Exception{}

--------------------------------------------------------

catch (Exception e) { //e用于接收try检测到的异常对象。

System.out.println("message:"+e.getMessage());//获取的是异常的信息。

System.out.println("toString:"+e.toString());//获取的是异常的名字+异常的信息。

e.printStackTrace();//打印异常在堆栈中信息;异常名称+异常信息+异常的位置。

}

---------------------------------------------------------

异常处理原则:功能抛出几个异常,功能调用如果进行try处理,需要与之对应的catch处理代码块,这样的处理有针对性,抛几个就处理几个。

 

特殊情况:try对应多个catch时,如果有父类的catch语句块,一定要放在下面。

 

throw throws关键字的区别:

throw用于抛出异常对象,后面跟的是异常对象;throw用在函数内。

throws用于抛出异常类,后面跟的异常类名,可以跟多个,用逗号隔开;throws用在函数上。

 

函数内容如果有throw,抛出异常对象,并没有进行try处理,那么函数上一定要声明,否则编译失败。

    (方法内使用throw抛出异常对象时,需使用try...catch处理或在方法上使用throws抛出异常。)

    注意,RuntimeException除外(函数内如果抛出的RuntimeExcpetion异常,函数上可以不用声明)。

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

 

异常分两种:

 编译时被检测异常

该异常在编译时,如果没有处理(没有抛也没有try),编译失败。

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

运行时异常(编译时不检测)-----RuntimeException及其子类

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

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

 

编译时被检查的异常和运行时异常的区别:

编译被检查的异常在函数内被抛出,函数必须要声明,否编译失败。

声明的原因:是需要调用者对该异常进行处理。

运行时异常如果在函数内被抛出,在函数上不需要声明。

不声明的原因:不需要调用者处理,运行时异常发生,已经无法再让程序继续运行,所以,不让调用处理的,直接让程序停止,由调用者对代码进行修正。

 

定义异常处理时,什么时候定义try,什么时候定义throws呢?

功能内部如果出现异常,如果内部可以处理,就用try

如果功能内部处理不了,就必须声明出来,让调用者处理。

 

try  catch  finally的几种结合方式:

有三个结合格式:

        a、try

             {

             }

             catch ()

             {

             }

        b、try

             {

             }

             finally

             {

             } 

        c、try

             {

             }

             catch ()

             {

             }

             finally

             {

             } 

 

这种情况,如果出现异常,并不处理,但是资源一定关闭,所以try  finally集合只为关闭资源

记住:finally很有用,主要用户关闭资源。无论是否发生异常,资源都必须进行关闭。

System.exit(0); //退出jvm,只有这种情况finally不执行。

 

自定义异常:当开发时,项目中出现了java中没有定义过的问题时,这时就需要我们按照java异常建立思想,将项目的中的特有问题也进行对象的封装。这个异常,称为自定义异常。

 

对于除法运算,0作为除数是不可以的。java中对这种问题用ArithmeticException类进行描述。对于这个功能,在我们项目中,除数除了不可以为0外,还不可以为负数。可是负数的部分java并没有针对描述。所以我们就需要自定义这个异常。

 

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


自定义异常的步骤:

1:定义一个子类继承ExceptionRuntimeException,让该类具备可抛性,让该类具备操作异常的共性方法。

2:通过throw 或者throws进行操作。

 

当要定义自定义异常的信息时,可以使用父类已经定义好的功能。

异常异常信息传递给父类的构造函数。

	class MyException extends Exception
	{
		MyException(String message)
		{
			super(message);
		}
	} 


异常的处理原则

1,处理方式有两种:try 或者 throws

2,调用到抛出异常的功能时,抛出几个,就处理几个,一个try对应多个catch

3,多个catch,父类的catch放到最下面。

4catch内,需要定义针对性的处理方式。不要简单的定义printStackTrace,输出语句。也不要不写。

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


当异常出现后,在子父类进行覆盖时,有了一些新的特点

1:当子类覆盖父类的方法时,如果父类的方法抛出了异常,那么子类的方法要么不抛出异常要么抛出父类异常或者该异常的子类,不能抛出其他异常。

2:如果父类抛出了多个异常,那么子类在覆盖时只能抛出父类的异常的子集。

 

注意:

如果父类或者接口中的方法没有抛出过异常,那么子类是不可以抛出异常的,如果子类的覆盖的方法中出现了异常,只能try不能throws

如果这个异常子类无法处理,已经影响了子类方法的具体运算,这时可以在子类方法中,通过throw抛出RuntimeException异常或者其子类,这样,子类的方法上是不需要throws声明的。

 

常见异常:

1、脚标越界异常(IndexOutOfBoundsException)包括数组、字符串;

空指针异常(NullPointerException

2、类型转换异常:ClassCastException

3空指针异常:NullPointerException

4、不支持操作异常;

异常要尽量避免,如果避免不了,需要预先给出处理方式。比如家庭备药,比如灭火器。



练习:

package pack;
// 1,异常:就是程序在运行时出现不正常情况。
//	异常由来:问题也是现实生活中一个具体的事物,也可以通过java;类的形式进行描述,并封装成对象。
//			其实就是java对不正常情况进行描述后的对象体现。
//	对于问题的划分:两种:一种是严重的问题,一种是非严重的问题。
//	对于严重的,java通过Error类进行描述。
//		对于Error一般不编写针对性的代码对其进行处理。
//	对于非严重固定,java通过Exception类进行描述。
//		对于Exception可以使用针对性的处理方式进行处理。
//	无论Error或者Exception都具有一些共性内容。
//	比如:不正常情况的信息,引发原因等。
//	Throwable:
//		|Error:
//		|Exception:
// 2,异常的处理
//	java提供了特有的语句进行处理。
//	try{需要被检测的代码}catch{处理异常的代码}finally{一定会执行的语句}
// 3,对捕获到的异常对象进行常见方法操作。
// 	String getMessage();获取异常的信息
// 在函数上声明异常。
// 便于提高安全性,让调处者进行处理,不处理编译失败。
// 对多异常的处理。
// 1,声明异常时,建议声明更为具体的异常,这样处理的可以更具体。
class Demo{
	// 在功能上通过throws的关键字声明了该功能有可能会出现问题。
	int div(int a,int b)throws ArithmeticException{
		return a/b;
	}
}
class ExceptionDemo1{
	public static void main(String[] args){
		try{
			Demo d=new Demo();
			System.out.println(d.div(9,3));
		}
		catch(ArithmeticException e){
			System.out.println("算术异常");
			System.out.println(e.getMessage());// 异常信息: /by zero
			System.out.println(e.toString());// 异常名称:异常信息。
			e.printStackTrace();// 异常名称,异常信息,异常出现的位置。
			// 其实jvm默认的异常处理机制,就是在调用printStackTrace方法。
		}
	}
}

package pack;
// 在函数上声明异常。
// 便于提高安全性,让调用者进行处理,不处理编译失败。
// 对多异常的处理。
// 1,声明异常时,建议声明更为具体的异常,这样处理的可以更具体。
// 2,对方声明几个异常,就对应有几个catch块。不要定义多余的catch块
//	如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
// 建议在进行catch处理时,catch中一定要定义具体处理方式。
// 不要简单的定义一句e.printStackTrace().
// 也不要简单的就写一条输出语句。
class Demo{
	int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException{
		int[] arr=new int[a];
		System.out.println(arr[3]);
		return a/b;
	}
}
class ExceptionDemo2{
	public static void main(String[] args){
		Demo d=new Demo();
		try{
			int x=d.div(3,3);
			System.out.println(x);
		}
		catch(ArithmeticException e){
			System.out.println("算术异常");
			e.printStackTrace();
		}
		catch(ArrayIndexOutOfBoundsException e){
			System.out.println("角标越界异常");
			e.printStackTrace();
		}
	}
}

package pack;
// 因为项目中会出现特有的问题,而这些问题并未被java所描述并封装。
// 所以对于这些特有的问题可以按照java对问题封装的思想。将特有的问题,进行自定义的异常封装。
// 自定义异常。
//	需求:在本程序中,对于除数是-1,也视为是错误的是无法进行运算的。
//	那么就需要对这个问题进行自定义的描述。
//	当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。
//	要么在内部try catch处理。要么在函数上声明让调用者处理。
//	一般情况在,函数内出现异常,函数上需要声明。
//	发现打印的结果中只有异常的名称,却没有异常的信息。
//	因为自定义的异常并未定义信息。
// 如何定义异常信息呢?
//	因为父类中已经把异常信息的操作都完成了。
//	所以子类只要在构造时,将异常信息传递给父类通过super语句。
//	那么就可以直接通过getMessage方法获取自定义的异常。
// 自定义异常:必须是自定义类继承Exception。
//	继承Exception原因:异常体系有一个特点,因为异常类和异常对象都被抛出。
//	他们都具备可抛性,这个可抛性是Throwable这个体系中独有特点。
//	只有这个体系中的类和对象才可以被throws和throw操作。
// throws和throw的区别:
//	throws使用在函数上。
//	throw使用在函数内。
// throws后边跟的是异常类,可以跟多个,用逗号隔开。
// throw后边跟的是异常对象。
class FuShuException extends Exception{
	private int value;
	FuShuException(String message){
		super(message);
	}
	FuShuException(String message,int value){
		super(message);
		this.value=value;
	}
	public int getValue(){
		return value;
	}
}
class Demo{
	int div(int a,int b)throws FuShuException{
		if(b<0)
			throw new FuShuException("被除数是负数: ",-1);
		return a/b;
	}
}
class ExceptionDemo3{
	public static void main(String[] args){
		Demo d=new Demo();
		try{
			int x=d.div(3,-1);
			System.out.println(x);
		}
		catch(FuShuException e){
			e.printStackTrace();
		}
	}
}

package pack;
// Exception中有一个特殊的子类异常RuntimeException 运行时异常。
// 如果在函数内抛出异常,函数上可以不用声明,编译一样通过。
// 如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。
// 注意:之所以不用再函数上声明,是因为不需要让调用者处理。
//	当该异常发生,希望程序停止,因为在运行时,
//	出现了无法继续运算的情况,希望停止程序后。对代码进行修正,
// 自定义异常时:如果该异常的发生,无法在继续进行运算的话。
// 就让自定义的异常继承RuntimeException.
// 对于异常分两种;
//	1,编译时被检测的异常。
//	2,编译时不被检测的异常(运行时异常。RuntimeException以及其子类)
class FuShuException extends RuntimeException{
	FuShuException(String message){
		super(message);
	}
}
class Demo{
	int div(int a,int b){
		if(b<0)
			throw new FuShuException("被除数是负数");
		return a/b;
	}
}
class ExceptionDemo4{
	public static void main(String[] args){
		Demo d=new Demo();
		try{
			System.out.println(d.div(3,-1));
		}
		catch(FuShuException e){
			e.printStackTrace();
		}
	}
}

package pack;
class Person{
	public void checkName(String name){
		if("曾强".equals(name))
			System.out.println("欢迎光临");
		else
			System.out.println("请勿入内");
	}
}
class PersonDemo8{
	public static void main(String[] args){
		// if(name.equals("李四"))//NullPointerException:空指针异常
		Person p=new Person();// if(name!=null && name.equals("李四"))
		p.checkName("曾强");
	}
}

package pack;
// 曾老师用电脑上课:
// 开始思考上课中出现的问题。
// 比如问题是:电脑蓝屏,电脑冒烟。
// 要对问题进行描述,封装成对象。
// 可是当冒烟发生后,会出现讲课进度无法继续。
// 出现了讲师的问题,课时计划无法完成。
class LanPinException extends Exception{
	LanPinException(String message){
		super(message);
	}
}
class MaoYanException extends Exception{
	MaoYanException(String message){
		super(message);
	}
}
class NoPlanException extends Exception{
	NoPlanException(String message){
		super(message);
	}
}
class comPut{
	private int start=1;
	public void setStart(int start){
		this.start=start;
	}
	public void run()throws LanPinException,MaoYanException{
		if(start==1)
			throw new LanPinException("蓝屏了");
		if(start==2)
			throw new MaoYanException("冒烟了");
		System.out.println("电脑运行");
	}
	public void relete(){
		System.out.println("电脑重启");
	}
}
class Teacher{
	private String name;
	private comPut put;
	Teacher(String name){
		this.name=name;
		put=new comPut();
	}
	public void setStart(int start){
		put.setStart(start);
	}
	public void relect()throws NoPlanException{
		try{
			put.run();
		}
		catch(LanPinException e){
			e.printStackTrace();
			put.relete();
		}
		catch(MaoYanException e){
			e.printStackTrace();
			System.out.println("课时无法继续");
			Test();
		}
	}
	public void Test(){
		System.out.println("自习");
	}
}
class ExceptionTest{
	public static void main(String[] args){
		Teacher t=new Teacher("曾老师");
		t.setStart(1);
		try{
			t.relect();
		}
		catch(NoPlanException e){
			e.printStackTrace();
			System.out.println("去换个老师继续上课");
		}
	}
}

package pack;
class FuShuException extends Exception{
	FuShuException(String message){
		super(message);
	}
}
class Demo{
	int div(int a,int b)throws FuShuException{
		if(b<0)
			throw new FuShuException("除数是负数");
		return a/b;
	}
}
class ExceptionDemo5{
	public static void main(String[] args){
		Demo d=new Demo();
		try{
			System.out.println(d.div(3,3));
		}
		catch(FuShuException e){
			e.printStackTrace();
		}
		finally{// finally中存放的是一定会被执行的代码。
			System.out.println("运算完毕");
		}
	}
}

package pack;
// 第一种格式:try{}catch{}第二种格式:try{}catch{}finally{}第三种格式:try{}finally{}
// 记住一点:catch是用于处理异常,如果没有catch就代表异常没有被处理过,如果该异常检测时异常,那么必须声明。
class Demo{
	public void method()throws RuntimeException{
		try{
			throw new RuntimeException();
		}
		finally{
			System.out.println("程序结束");
		}
	}
}
class FinallyDemo{
	public static void main(String[] args){
		Demo d=new Demo();
		d.method();
	}
}

package pack;
//	异常在子父类覆盖中的体现:
//	1,子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
//	2,如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
//	3,如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
//	如果子类方法发生了异常,就必须要进行try处理,绝对不能抛。
class AException extends Exception{}
class BException extends AException{}
class CException extends BException{}
class Fu{
	void show()throws AException{}
}
class Zi extends Fu{
	void show()throws BException{}
}
class ABCException{
	public static void main(String[] args){
		Zi z=new Zi();
		z.show();
	}
}

package pack;
//有一个圆形和长方形,都可以获取面积,对于面积如果出现非法的数值,
//	视为获取面积时出现的问题。问题通过异常来表示。
//先要对这个程序进行基本的设计。
class NoPlanException extends Exception{
	NoPlanException(String message){
		super(message);
	}
}
interface Inter{
	void getArea();
}
class Res implements Inter{
	private int len,wid;
	Res(int len,int wid)throws NoPlanException{
		if(len<0&&wid<0)
			throw new NoPlanException("非法值");
		this.len=len;
		this.wid=wid;
	}
	public void getArea(){
		System.out.println("长: "+len*wid);
	}
}
class Circle implements Inter{
	private int readius;
	public static final double PI=3.14;
	Circle(int readius)throws NoPlanException{
		if(readius<0)
			throw new NoPlanException("非法值");
		this.readius=readius;
	}
	public void getArea(){
		System.out.println("圆: "+readius*readius*PI);
	}
}
class ExceptionTest{
	public static void main(String[] args)throws NoPlanException{
		Res r=new Res(2,3);r.getArea();
		Circle c=new Circle(5);c.getArea();
	}
}

// 异常:是什么?是对问题的描述,将问题进行对象的封装。
//	异常体系:Throwable
//				|--Erroe
//				|--Exception
//					|--RuntimeException
// 异常体系的特点:异常体系中的所有类,以及建立的对象都具备可抛性。
//		也就是说可以被throw与throws关键字所操作,只有异常体系具备这个特点。
//	throw与throws的用法:
//	throw定义在函数内,用于抛出异常对象。
//	throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。
//	当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,否则编译失败。
//	注意:RuntimeException除外,也就是说,函数内如果抛出的RuntimeException异常,函数上可以不用声明。
//	如果函数声明了异常,调用者需要进行处理,处理方法可以throws可以try。
// 异常有两种:
//	编译时被检测异常,
//		该异常在编译时,如果没有处理(没有抛也没有try),编译失败。
//		该异常被标识,代表这可以被处理。
//	运行时异常(编译时不检测)。
//		在编译时,不需要处理,编译器不检查。
//		该异常的发生,建议不处理,让程序停止,需要对代码进行修正。
// 异常处理语句:try{需要被检测的代码}catch{处理异常的代码}finally{一定会执行的代码}
//	有三个结合格式:1,try{}catch{}2,try{}catch{}finally{}3,try{}finally{}
//	注意:1,finally中定义的通常是关闭资源代码,因为资源必须要释放。
//		  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内,需要定义针对性的处理方式,不要简单的定义printSrackTrace,输出语句。
//		也不要不写。当捕获到的异常,本功能处理不了时,可以继续在catch中抛出
//		try{throw new Aexception();}catch(AException e){throw e;}
//		如果该异常处理不了,但并不属于该功能出现的异常。可以将异常转换后没再抛出和该功能相关的异常。
//		或者异常可以处理,当需要将异常产生后和本功能相关的问题提供出去,让调用者知道,并处理,也可以将捕获异常处理后,转换新的异常。
//		try{throw new Aexception();}catch(AException e){//对AException处理,throw new BException();}
// 异常的注意事项:
//	在子父类覆盖时:
//	1,子类抛出的异常必须是父类异常的子类或者子集。
//	2,如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛。
//	参阅:ExceptionTest.java老师用电脑上课,ExceptionTest1.java图形面积。
package pack;
//javac -d . most2.java 编译代码 
//java pack.PackageDemo 运行代码
class PackageDemo{
	public static void main(String[] args){
		System.out.println("Hello JAVA");
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值