java学习:异常

1、概述

因为程序出错是不可避免的,所以为了提高程序的健壮性,所有的高级语言都添加了异常的处理方式,被称为异常处理机制。注意开发中的逻辑错误和语法错误不是异常。

java把异常分为两大类:

Error:jvm无法处理和解决的严重问题(类似于重大交通事故) — >不做处理;
Exception:可以处理 —> 处理。

img

java.lang.Error:

public static void main(String[] args) {
  //java.lang.StackOverflowError 栈溢出
  test();
 
  //java.lang.OutOfMemoryError 内存溢出
Integer[] arr = new Integer[1024*1024*1024];

}
public static void test() {
  test();
}

java.lang.Exception:

偶然出现的编程错误导致的一般问题,可以使用异常处理机制进行处理,目的是让程序能够处
理“错误”,提高程序的健壮性,看起来比较”智能“
处理方式:
1、遇到错误终止程序
2、处理错误,给出提示,继续运行

捕捉错误的时机:
编译时期:编译时期出现错误,需要事先强制处理(checked)。
运行时期:运行时期出现错误(unchecked)。

2、常见异常类型

2.1 编译时期异常:(checked)

​ (1)IOException

​ FileNotFoundException

​ (2)ClassNotFoundException:指定的类不存在

2.2 运行时期异常:(unchecked)

java.lang.RuntimeExcepiton
NullPointExcepiton: 空指针异常
ArrayIndexOutOfBoundsException: 数组下标越界
ClassCastException:类型转换异常
NumberFormatException:数字格式异常
InputMismatchException:输入类型不匹配
ArithmeticException:数学算术异常

//java.lang.NullPointerException
String str = null;
System.out.println(str.length());

//java.lang.ArrayIndexOutOfBoundsException
String[] arr = new String[4];
System.out.println(arr[5]);

//java.lang.ClassCastException
Object obj = new Date();
String str = (String)obj;

//java.lang.NumberFormatException
int num = Integer.parseInt("abc");

//InputMismatchException
Scanner input = new Scanner(System.in);
System.out.println("请输入一个数:");
int res = input.nextInt();
input.close();

//java.lang.ArithmeticException
int res = 10 / 0;

3、处理异常

3.1 处理异常模型:
(1)抓取:进行异常处理

方式一:try-catch-finally;
方式二:throws + 异常类型。

(2)抛出

程序在运行过程中一但出现异常,就会在异常出现的地方生产异常对象,并将此抛出,其后代码不再运行。

3.2 try-catch-finally(自己处理)

格式:

try{
//可能出现异常的代码
}catch(异常类型 变量名称){
//处理异常代码
}catch{
//异常处理代码
}
...
finally{
//一定要执行的代码
}

演示代码:

String str = "abc"; //"abc" 
try {
int num = Integer.parseInt(str);// 出现异常
//出现异常 --- 没有机会执行后面代码 
Object obj = new Date(); 
String str2 = (String)obj; 
System.out.println(str2); 

}catch(NullPointerException e) { 
System.out.println("NullPointerExceptio n"); 

}catch(NumberFormatException e) { 
e.printStackTrace(); //异常堆栈信息
 //System.out.println(e.getMessage()); 
 //System.out.println("NumberFormatException"); 
 
 }catch(Exception e) { 
 e.printStackTrace(); //异常堆栈信息 
 System.out.println("Exception"); 
 }
 System.out.println("执行 ---------------- "); 

说明:

  • try将可能出现的异常代码包含起来,一但代码出现异常将会在出现异常的地方生成异常对象并抛给系统,之后跳转到catch区域。
  • catch则可以根据是否匹配(对应的类型或子类)捕捉到异常对象,再进行异常代码的处理,
    处理完异常代码逻辑跳出try-catch块执行剩余的代码,(可能不会执行所有的catch块)。
  • 在try-catch声明的变量 不能跳出该结构被找到,所以有时候需要在try-catch块之外声明变量。
  • try-catch将编译时出现的异常推迟到运行时异常处理,但仍然可能出错,所以在开发中运行时异常我们一般不做处理。

演示代码(finally):

try {
int num1 = 10; 
int num2 = 0; 
int res = num1 / num2; 
}catch(ArithmeticException e) { 
//异常中抛出异常,执行顺序是? 
System.out.println("-------e------ "); 
Integer.parseInt("abc"); e.printStackTrace(); 
}finally { 
System.out.println("一定会执行 ------- --"); 
}
//System.out.println("--------");

说明:

  • fifinally声明的语句一定会被执行,即使catch中出现异常,或try-catch中有return语句也会被执行。
  • 通常jvm不能够及时回收的资源可放入fifinally语句中,比如:数据库连接,输入输出流等资源的
    释放。
3.3 throws + 异常模型(模型处理)

写在方法的声明处,说明此方法执行时会抛出异常,一旦程序在执行中出现异常,仍然会在异常代码处生成对象,此对象如果满足声明条件(匹配或子类),则异常就会抛出,异常之后的代码不会被执行。
此方法未处理异常,只是抛给调用者来处理。

public class Test3 {
	public static void main(String[] args) { 
		try {
			method2(); 
		} catch (IOException e) { 
			e.printStackTrace(); 
		} 
	}
	
	public static void method2() throws IOException { 
		method(); 
	}
	
	public static void method() throws IOException {
		File file = new File("hello.txt");
		FileInputStream input = new FileInputStream(file); //读取hello.txt数据 
		int data = input.read(); //循环读取数据 
		while(data != -1) { //判断是否有数据
			System.out.println((char)data); 
			data = input.read();
		}
		input.close();
	}
} 
3.4 注意事项
  • 如果父类中被重写的方法没有throws抛出异常,则子类重写的方法不能抛出,子类只能try-catch处理。
  • 子类重写父类方法抛出的异常,不能大于重写的父类方法的异常。

4、手动生成异常throw

class Student {
	private int id;
	// 方法声明异常
	public void regist(int id) throws Exception {
		if (id > 0) {
			this.id = id;
		} else {
		// System.out.println("输入的数据有误!");
		// 手动抛出异常
		throw new Exception("输入的数据有误!");
	}
}
	@Override
	public String toString() {
		return "Student [id=" + id +"]";
	}
}

public class Test4 {
	public static void main(String[]args) {
     		Student stu = new Student();
     		try {
			stu.regist(-10);
		} catch (Exception e) {
			System.out.println(e.getMessage());
			//e.printStackTrace();
		}
	}
}

5、用户自定义异常

一般的用户的自定义异常类都是RuntimeException的子类;
自定义异常类通常需要编写几个重载的构造器;
自定义异常需要提供serialVersionUID;
自定义异常通常通过thrwos抛出;
自定义异常最重要的是异常类型的名称,当异常出现时,可以根据名称判断异常类型;

步骤:
创建MyException类继承Exception;
重写父类的方法:构造方法无参及有参(String message)。

/*** 自定义异常类 
* @author Administrator
**/ 
public class MyException extends Exception{
	public MyException() {
 		super(); 
 	}
 	public MyException(String message) { 
 		super(message);
 	 } 
 } 

public class MyExpTest { 
   public void regist(int num) throws MyException {
   	 if(num < 0) { 
   	 	throw new MyException("人数为负,不合理"); 
   	 }else { System.out.println("登记人 数:" + num); 
   	 }
    }
   public void manager() { 
   	  try {regist(-10);
   	   } catch (MyException e) { 
   	   	System.out.println("登记失败, 错误为:" + e.getMessage());
   	   	 //e.printStackTrace(); 
   	   } 
   	System.out.println("本次登记结束");
   }
   public static void main(String[] args) {
   	 MyExpTest test = new MyExpTest(); 
		test.manager(); }
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值