/*
- 异常处理方式1 try-catch-finally
- 1,Java采用的异常处理机制,是将异常处理的程序代码集中在一起,与正常的程序代码分开,
- 过多的if-else分支会导致程序的代码加长、臃肿,可读性差。因此采用异常处理机制。使得程序简洁、优雅,并易于维护。
- 2,Java提供的是异常处理的抓抛模型。
- 步骤一:抛出异常
- 程序在执行过程中如出现异常,会生成一个异常类对象,该异常对象将被提交给Java运行时系统,
- 这个过程称为抛出(throw)异常,一旦抛出异常对象后,其后代码不再执行。
- 异常对象的创建方式:
- 1,由虚拟机自动生成:程序运行过程中,虚拟机检测到程序发生了问题,如果在当前代码中没有找到相应的处理程序,
- 就会在后台自动创建一个对应异常类的实例对象并抛出——自动抛出
- 2,由开发人员手动创建:Exception exception = new ClassCastException();
- 创建好的异常对象不抛出对程序没有任何影响,和创建一个普通对象一样
- 步骤二:捕获异常
- 捕获异常就是对异常进行处理,有两种常用方式:1,try-catch-finally 2,throws
- 3,方式1:try-catch-finally的使用方式
- try{
- //可能会出现异常的代码块
- }catch(异常类型1 变量名1){//变量名常用e,也可以更换
- 处理异常方式1
- }catch(异常类型2 变量名2){
- 处理异常方式2
- }…//根据实际情况,可以设置多个catch
- finally{
- 一定会执行的代码块//finally是可选结构,与switch-case中的default一样
- }
- 说明:
- 1,try-catch结构是可以嵌套的。
- 2,使用try将可能异常的代码块包起来,一旦在运行时出现异常,会生成对应异常类的对象,
- 根据此对象的类型,会在catch语句中匹配。
- 3,一旦try中的异常匹配到catch中的异常类型时,会执行catch中的处理语句,
- 处理完成就会跳出当前的try-catch结构,(没有finally结构的情况下)继续执行之后的代码
- 4,catch中异常类型如果没有子父类的关系,位置可以任意,如果有子父类关系,子类要写在上面,否则会报错。
- 5,catch常用的两个方法。1,String getMessage(),返回一个字符串,2printStackTrace().返回值void类型。
- printStackTrace()中也会输出getMessage()的信息。比较常用
- 6,try结构中定义的变量是局部变量,出了大括号外不能调用。finally中也不能调用。
- 7,快速生成try-catch结构,在eclipse中可以选择代码快后使用右键选择surround with 下的try-catch包裹代码快。
- 4,finally的使用
- 1捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,
- 使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。
- 2不论在try代码块中是否发生了异常事件,catch语句是否执行,
- catch语句是否有异常,catch语句中是否有return,finally块中的语句都会被执行。
- 3,finally语句和catch语句是任选的
- 4,在有返回值的方法中,如果要在try-catch结构中输出返回值,需要在try中和每个catch中都
- 定义一个return值。
- 5,finally使用的地方,类似数据库连接,输入输出流,网络编程中的socket,在JVM中无法自动回收。
- 需要手动关闭释放资源的代码,需要声明在finally中,确保关闭,防止内存泄漏。
- 5,总结
- 1使用try-catch-finally结构处理编译时异常,是让程序在编译时不报错,但在运行时依然可能报错。
- 相当于使用try-catch-finally结构将一个编译时可能出现的问题延迟到运行时出现。
- 2开发中运行时异常比较常见,通常不针对运行时异常添加try-catch-finally结构,
- 而针对编译时异常,需要考虑做try-catch处理,否则程序无法运行。
*/
package exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Exception_Handle {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = 0;
try {
int i = 10;
num = 20;
System.out.println("请输入一个1-100范围内的整数");
int n = scan.nextInt(); //当在控制台输入小数时,报异常
if(n < 1 || n > 100) {
throw new RuntimeException("数据超出范围");//只抛出异常,没有捕获,程序不会执行后面的代码
}
System.out.println(n);
}catch(NullPointerException e) {//如果只有这个异常处理措施,则会自动抛出异常,因为异常类型不匹配
System.out.println("没有数据");
}catch(InputMismatchException a) {
a.getMessage();
System.out.println("输入数据类型错误");//异常捕获处理后,会继续执行后面的代码//
// System.exit(0);//之后的finally不被执行
}catch(Throwable e) {
System.out.println("天知道什么异常");//异常的父类写在后面,与if-else中的规则相同,包含关系中范围大的在后面
}
finally {
System.out.println("输入结束");
scan.close();
}
System.out.println(num);
// System.out.println(i);//try中的局部变量无法在外部使用
System.out.println("结束测试1");
try {
Object o = new Date();
String s = (String)o;
}catch(ClassCastException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
System.out.println("结束测试2");
Exception_Handle test = new Exception_Handle();
int i = test.method();
System.out.println(i);
System.out.println("结束测试3");
test.method2();
System.out.println("结束测试4");
}
public int method() {
try {
String s = null;
System.out.println(s.charAt(1));
return Integer.parseInt(s);
}catch(NullPointerException e) {
e.printStackTrace();
// int[] array = new int[] {3,2,1,0};
// System.out.println(array[4]);//catch语句中可能也有异常,不影响finally语句的输出
return 404;
}catch(Exception e) {
e.printStackTrace();
return 502;
}finally {
System.out.println("Hello");
return 12;//finally中的return值是最终输出的值
}
}
public void method2(){
FileInputStream fis = null;
try {
File file = new File("E:\\eclipse-workspace\\Contacts\\bin\\2.txt");
fis = new FileInputStream(file);
int date = fis.read();
while(date != -1) {
System.out.print((char)date);
date = fis.read();
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(Exception e) {
e.printStackTrace();
}finally {
try {
if(fis != null) {//防止出现空指针异常,file可能无法找到,此时fis无法创建
fis.close();//当fis创建成功后,确保关闭。
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}