Java——异常

异常

Java代码在运行时期发生的问题就是异常。在Java中,把异常信息封装成了一个类。当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置、原因等)。

异常继承体系:

 Throwable: 它是所有错误与异常的超类(祖宗类)

  |- Error 错误

  |- Exception 编译期异常,进行编译JAVA程序时出现的问题

    |- RuntimeException 运行期异常, JAVA程序运行过程中出现的问题

异常与错误的区别:

异常:指程序在编译、运行期间发生了某种异常(XxxException),我们可以对异常进行具体的处理。若不处理异常,程序将会结束运行。

错误:指程序在运行期间发生了某种错误(XxxError)Error错误通常没有具体的处理方式,程序将会结束运行。Error错误的发生往往都是系统级别的问题,都是jvm所在系统发生的,并反馈给jvm的。我们无法针对处理,只能修正代码。

public static void main(String[] args) { 
    //该句运行时发生了内存溢出错误OutOfMemoryError,开辟了过大的数组空间,导致JVM在分配数组空间时超出了JVM内存空间,直接发生错误。
}

1、抛出异常throw

java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。

  • 1,创建一个异常对象。封装一些提示信息(信息可以自己编写)

  • 2,需要将这个异常对象告知给调用者。

throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。

使用格式:

throw new 异常类名(参数);

2、声明异常throws

将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有进行捕获处理,那么必须通过throws进行声明,让调用者去处理。

声明异常格式:

修饰符返回值类型方法名(参数) throws 异常类名1,异常类名2… { }

/*
 *  异常中的关键字
 *    throw,在方法内部,抛出异常的对象
 *    throw 后面,必须写new 对象,必须是异常的对象,必须是Exception或者子类
 *    
 *  方法中声明异常关键字
 *    throws 用于在方法的声明上,标明次方法,可能出现异常
 *    请调用者处理
 *    throws 后面必须写异常类的类名
 *    
 *    调用了一个抛出异常的方法,调用者就必须处理
 *    不处理,编译失败
 */
public class ExceptionDemo {
	// main方法在往上(JVM)报告这个异常
	public static void main(String[] args) throws Exception {
		int[] arr = {};
		int i = getArray(arr);
		System.out.println(i);
	}
	//使用throws声明异常,报告给调用者
	public static int getArray(int[] arr) throws Exception {
		//对方法参数进行合法性的判断,进行判断是不是null
		if( arr == null){
			//抛出异常的形式,告诉调用者
			//关键字 throw
			throw new Exception("传递数组不存在");
		}
		
		//对数组进行判断,判断数组中,是不是有元素
		if(arr.length == 0){
			//抛出异常的形式,告诉调用者,数组没有元素
			throw new Exception("数组中没任何元素");
		}
		int i = arr[arr.length-1];
		return i*2;
	}
}

3、捕获异常

Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式的处理

/*
 *  异常的处理方式:
 *    try...catch...finally
 *    格式:
 *      try{
 *        被检测的代码
 *        可能出现异常的代码
 *      }catch(异常类名 变量){
 *         异常的处理方式
 *         循环,判断,调用方法,变量
 *      }finally{
 *         必须要执行代码
 *      }
 */
public class ExceptionDemo1 {
	public static void main(String[] args) {
		int[] arr = null;
		try{
			int i = getArray(arr);
			System.out.println(i);
			
		}catch(NullPointerException ex){	// 多异常捕获的时候,在上面的等级必须要小于等于下面的等级
			System.out.println("###"+ex);
			
		}catch(ArrayIndexOutOfBoundsException ex){
			
			System.out.println("!!!!!!"+ex);
		}finally{
		System.out.println("Game Over");
		}
	}
	/*
	 * 定义方法,抛出异常
	 * 调用者使用try catch
	 */
	 public static int getArray(int[] arr)throws NullPointerException,ArrayIndexOutOfBoundsException{
		 //对数组判空
		 if( arr == null){
			 //手动抛出异常,抛出空指针异常
			 throw new NullPointerException("数组不存在");
		 }
		 //对数组的索引进行判断
		 if( arr.length < 3){
			 //手动抛出异常,抛出数组的索引越界异常
			 throw new ArrayIndexOutOfBoundsException("数组没有3索引");
		 }
		 return arr[3]+1;
	 }
}

Throwable类中的方法

三个方法,都和异常的信息有关系

  • String getMessage() 对异常信息的详细描述    异常了!
  • String toString() 对异常信息的简短描述   java.lang.Exception: 异常了!
  • void printStackTrace() 将异常信息追踪到标准的错误流    异常信息最全,JVM默认调用方法也是这个方法

运行时异常

运行时异常不用声明,也不用捕获

/*
 *  异常分为编译异常和运行时期异常
 *    编译异常: 调用了抛出异常的方法,不处理编译失败  (try  throws)
 *    运行异常: 抛出的异常是RuntimeException类,或者是他的子类
 *  
 *  运行异常的特点:
 *     方法内部抛出的异常是运行异常, new XXXException
 *     方法的声明上,不需要throws语句,调用者,不需要处理
 *     设计原因:
 *        运行异常,不能发生,但是如果发生了,程序人员停止程序修改源代码
 *        
 *        运行异常: 一旦发生,不要处理,请你修改源代码, 运行异常一旦发生,后面的代码没有执行的意义
 */
public class RuntimeExceptionDemo {
	public static void main(String[] args) {
			double d = getArea(1);
			System.out.println(d);
	}
	
	/*
	 *  定义方法,计算圆形的面积
	 *  传递参数0,或者负数,计算的时候没有问题
	 *  但是,违反了真实情况
	 *  参数小于=0, 停止程序,不要在计算了
	 */
	public static double getArea(double r){
		if(r <= 0){
			throw new RuntimeException("圆形不存在");
		}
		return r*r*Math.PI;
	}
	
	
	public static void function(){
		int[] arr = {1,2,3};
		//对数组的5索引进行判断,如果5索引大于100,请将5索引上的数据/2,否则除以3
		//索引根本就没有
		if(arr[5] > 100){
			arr[5] = arr[5]/2;
		}else{
			arr[5] = arr[5]/3;
		}
	}

继承的异常问题

如果父类中的方法声明了异常,子类重写后,可以声明异常(声明的异常必须等级小于等于父类)也可以不声明异常。

如果父类中的方法中没有声明异常,子类重写后,不可以声明异常。

4、自定义异常

一般我们自定义的异常都是继承于RuntimeException,不用声明,也不用捕获。

ExceptionDemo.java

public class ExceptionDemo {
	public static void main(String[] args) {
		
		int avg = getAvg(50,60,-70,80);
		System.out.println(avg);
		
	}
	/*
	 * 传递成绩,计算成绩的平均数
	 * 成绩没有负数,需要抛出异常,停止运算
	 */
	public static int getAvg(int...source){
		int sum = 0 ;
		for(int s : source){
			if( s < 0){
				throw new FuShuException("成绩错误 "+s);
			}
			sum = sum + s;
		}
		return sum/source.length;
	}
}

FuShuException.java

/*
 *  自定义异常
 *    继承Exception,或者继承RuntimeException
 *    构造方法中,super将异常信息,传递给父类
 */
public class FuShuException extends RuntimeException{
	public FuShuException(String s){
		super(s);
	}
	
	public FuShuException(){}
}
原文地址:https://www.cnblogs.com/x54256/p/8434980.html