java入门 -- 异常处理

异常

1 异常的分类

▪ 在Java语言中,将程序执行中发生的不正常情况称为“异常”,Java在编译或运行或者运行过程中出现的错误 (例如要求用户输入数字,但是用户输入了一串字符串,此时就会发生异常)

异常的根接口Throwable,其下有2个子接口,Error和Exception。

▪ Error:指的是JVM错误,这时的程序并没有执行,无法处理;
▪ Exception:指的是程序运行中产生的异常,用户可以使用处理格式处理。

java入门 -- 异常处理
运行时异常

▪ 是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。
▪ 对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。

编译时异常

▪ 是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。编译器要求Java程序必须捕获或声明所有编译时异常。
▪ 对于这类异常,如果程序不处理,可能会带来意想不到的结果。

2 异常的处理

方式一:
try…catch、 try…catch…finally、 try…finally

try{
...... //可能产生异常的代码
}
catch( ExceptionName1 e ){
...... //当产生ExceptionName1型异常时的处置措施
}
catch( ExceptionName2 e ){
...... //当产生ExceptionName2型异常时的处置措施
}[ finally{
...... //无论是否发生异常,都无条件执行的语句
} ]

▪ catch 不能独立于 try 存在
▪ 在 try/catch 后面添加 finally 块并非强制性要求的
▪ catch里面不能没有内容
▪ 如果程序可能存在多个异常,需要多个catch进行捕获,其没有先后顺序
▪ 当捕获到异常时执行相应catch,没有捕获到异常时执行finally

方式二:
throws

▪ 如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
▪ 在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。
重写方法不能抛出比被重写方法范围更大的异常类型

public class ReturnFinally {
	public static void main(String[] args) {
//		int i = test01();
//		System.out.println(i);
		
		int i = test02();
		System.out.println(i);
	}

	private static int test02() {
		int num = 10;
		try {
			System.out.println(num);
			return num;
		} catch (Exception e) {
			num += 10;
			System.out.println("发生异常");
		} finally {
			num++;
			System.out.println("必须要执行的代码");
		}
		return num;
	}

	public static int test01() {
		int num = 10;
		try {
			System.out.println(num);
			// 在函数中,如果在finally之前,使用return关键字,则在return完成前,执行finally,再return
			return num + 1;
		} catch (Exception e) {
			System.out.println("发生异常");
		} finally {
			System.out.println("必须要执行的代码");
		}
		return num + 2;
		
	}
}
public class Error {
  public static void main(String[] args) throws RuntimeException{
	
	  try {
		  MyException(5,-1);
	} catch (Exception e) {
		System.out.println(e.getMessage());
	}finally {//必须执行
		System.out.println("必须执行");
		
	}
	  System.out.println("55");
}
	
	public static void MyException(int i,int j) {//throws RuntimeException{
		int t;
		
			t = i/j;
		
		
		System.out.println("11");
		if(i<0||j<0) {
			System.out.println("222");
			throw new RuntimeException ("数字必须为正数");//message
			
		}
		System.out.println("33");
		System.out.println(t);
		System.out.println("44");
		
	}
}

3 手动抛出异常

手动抛出异常使用的关键字是 throw

▪ 首先要生成异常类对象,然后通过throw语句实现抛出操作(提交给Java运
行环境)。
▪ 可以抛出的异常必须是Throwable或其子类的实例。

  public static void getDrink(int drinkType) throws DrinkNotFoundException  {  //声明异常
	  
		if ( drinkType<1||drinkType>3){
		throw new DrinkNotFoundException("请输入正确的编号");
		}
      
      switch (drinkType) {
      case 1:
          System.out.println("咖啡");
          break;
      case 2:
          System.out.println("啤酒");       
                  break;
      case 3:
          System.out.println("牛奶");
          break;

      default:
          break;
      }
  
}

4 用户自定义异常类

一般情况下,用户自定义异常类都是RuntimeException的子类。
用户自己的异常类必须继承现有的异常类。这里继承的是 Exception。

public class DrinkNotFoundException extends Exception {	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public DrinkNotFoundException() {
	    super();
	    // TODO Auto-generated constructor stub
	}
	public DrinkNotFoundException(String string) {
	      super(string);
		// TODO Auto-generated constructor stub
		
	}

}

这个异常类就是上面手动抛出异常的自定义异常类
下面是测试类

private static Scanner sc;

	public static void main(String[] args)  {
		Coffee c = new Coffee();
		Milk m = new Milk();
		Beer b = new Beer();
		sc = new Scanner(System.in);
		System.out.println("请输入你要购买的饮料的编号:");
		try {
		int i = sc.nextInt();
		Drink.getDrink(i);
		if(i==1){
		c.taste();
		}else if(i==2){
		b.taste();
		}else if(i==3){
		m.taste();
		} 
		} catch (Exception e) {		
		System.out.println(e.getMessage());
		}
		}

java入门 -- 异常处理
当用户输入的编号不是1-3的话就会产生异常,手动抛出到自定义异常类,输出自己编辑的message。

public class yic {
 public static void main(String[] args) throws Class12.MyException {
	 MyException(5,0);
	 
}
	public static void MyException(int i,int j) throws Class12.MyException  {
		try {
			int t;
			t = i/j;
			System.out.println(t);
		} catch (ArithmeticException e) {
			// TODO Auto-generated catch block
			throw new MyException("不能为0");
		}
	}
}
public class MyException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public MyException(String string) {
		// TODO Auto-generated constructor stub
		super(string);
	}

	
 
}

java入门 -- 异常处理
大家不要误以为红色字体就是自己的代码有错误,要仔细分析里面的错误信息,例如这里就自定义了错误信息。

5 当return遇上finally

我们之前说finally里的语句是必须执行的,语句执行到return是直接结束掉函数。


public class ReturnFinally {
	public static void main(String[] args) {
		int i = test01();
		System.out.println(i);
		
		
	}
	public static int test01() {
		int num = 10;
		try {
			System.out.println(num);
			// 在函数中,如果在finally之前,使用return关键字,则在return完成前,执行finally,再return
			return num + 1;
		} catch (Exception e) {
			System.out.println("发生异常");
		} finally {
			System.out.println("必须要执行的代码");
		}
		return num + 2;
		
	}
}

此时执行的是 num+1,并没有执行num+2,
在函数中,如果在finally之前,使用return关键字,则在return完成前,执行finally,再return。可以认为此时return已经拿到了自己所要的数据,只是给finally做出了让步,让其先执行。
java入门 -- 异常处理

public static int test01() {
		int num = 10;
		try {
			System.out.println(num);
			// 在函数中,如果在finally之前,使用return关键字,则在return完成前,执行finally,再return
			return num + 1;
		} catch (Exception e) {
			System.out.println("发生异常");
		} finally {
			System.out.println("必须要执行的代码");
			return num + 2;
		}	
	}

如果将return放入finally中执行的结果是
java入门 -- 异常处理
一般不建议在finally中放入这种代码,finally需要放入一些比较重要的代码,避免因为错误而延误这些代码的运行。

上一篇:thymeleaf中的内联[ [ ] ]


下一篇:C# 网页图片爬虫的几种技术基础