异常处理部分

本文详细讲解了Java异常处理模型(try-catch-finally)、异常的捕获与处理、throws关键字的应用,以及如何自定义异常类。通过实例展示了如何正确处理StackOverflowError和OOM异常,以及资源管理的最佳实践。
摘要由CSDN通过智能技术生成
package yichang01;
/*
 * Error:
 * java虚拟机无法处理的严重问题。如JVM内部系统错误、资源耗尽等情况。比如:StackOverflowError和
 * OOM。一般不编写针对性的代码进行处理
 */
public class ErrorTest {
	public static void main(String[] args) {
		//1.java.lang.StackOverflowError
		//main(args);   //栈溢出
		//2.java.lang.OutOfMemoryError 堆溢出OOM
		Integer[] integers=new Integer[1024*1024*1024];
	}
}

package yichang02;
/*
 * 一、异常地处理:抓抛模型
 * 
 * 过程一:"抛":程序在正常执行过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,
 * 			并将此对象抛出,一旦将此对象抛出,其后的代码就不会被执行
 * 		关于异常的产生:①系统自动生成的异常对象
 * 				   ②手动地生成一个异常对象,并抛出(throw)
 * 过程二:"抓":可以理解为异常的处理方式,①try-catch-finally ②throws 
 * 
 * 二、try-catch-finally的使用
 * try{
 * 		//可能出现异常的代码
 * }
 * catch(异常类型1 变量名){
 * 		//处理异常的方式1
 * }
 * catch(异常类型2 变量名){
 * 		//处理异常的方式2
 * }
 * catch(异常类型3 变量名){
 * 		//处理异常的方式3
 * }
 * ...
 * finally{
 * 		//一定会执行的代码
 * }
 * 
 * 
 * 说明:
 * 1.finally是可选的
 * 2.使用try将可能出现异常的代码块包装起来,在执行过程中,一旦出现异常,就会生成一个对应
 *   异常类的对象,根据此对象的类型,去catch中进行匹配
 * 3.一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常处理。一旦处理完成
 *   就跳出当前的try-catch结构(在没有写finally的情况下),继续执行其后的代码。
 * 4.catch中的异常类型如果没有子父类关系,则声明顺序无所谓
 * 	 catch中的异常类型如果有子父类关系,则子类一定要声明在父类之前。否则报错。
 * 5.常用的异常处理方式:① String getMessage()  ② printStackTrace()
 * 6.在try结构中声明的变量,在出了try结构之后,就不能再被调用
 * 7.try-catch-finally结构可以嵌套
 * 
 * 体会1:使用try-catch-finally处理编译时异常,使得程序在编译时就不报错,但是运行时仍可能报错
 *     相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现
 * 体会2:由于运行时异常比较常见,所以我们一般不针对运行时异常编写try-catch-finally
 *      针对编译时异常,一定要考虑异常的处理
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.junit.Test;

public class ExceptionTest1 {
	@Test
	public void test6() {
		try {
			File file=new File("hello.txt");
			FileInputStream fis=new FileInputStream(file);
			
			int data = fis.read();
			while(data!=-1) {
				System.out.println((char)data);
				data=fis.read();
			}
			fis.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Test
	public void test1() {
		String str="123c";
		int num=0;
		try {
//			int num = Integer.parseInt(str);
			num = Integer.parseInt(str);
			System.out.println("hello-1");
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			System.out.println("出现数值转换异常!");
			//String getMessage():
			System.out.println(e.getMessage());  //For input string: "123c"
			e.printStackTrace();
		}
		System.out.println("hello-2");
		System.out.println(num);
	}
}

package yichang02;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
 * 异常处理方式2:throws+异常类型
 * 1."throws+异常类型" 写在方法声明处,指出此方法在执行时,可能会抛出的异常。
 *   一旦方法体执行时,出现异常,会在异常代码处生成一个异常类的对象,此对象满足throws
 *   后异常类型时就会被抛出。出现异常代码后的代码就不会被执行,即不存在finally的结构
 * 2.try-catch-finally:真正地将异常给处理掉了
 *   throws只是将异常抛给了方法的调用者。并没有将异常真正地处理掉。
 * 3.开发中如何选择使用try-catch-finally还是throws
 *   3.1如果父类被重写的方法中没有用throws,则子类重写的方法也不能用throws,意味着如果
 *      子类若有异常,只能用try-catch-finally结构处理。
 *   3.2执行的方法a时,先后又调用了其他几个方法,这几个方法是递进关系执行的,建议这几个方法
 *   	使用throws处理,方法a使用try-catch-finally处理
 */
public class ExceptionTest2{
	public static void main(String[] args) {
		try {
			method2();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void method2() throws IOException{
		method1();
	}
	public static void method1() throws FileNotFoundException,IOException
	{
		File file=new File("hello.txt");
		FileInputStream fis=new FileInputStream(file);
		
		int data = fis.read();
		while(data!=-1) {
			System.out.println((char)data);
			data=fis.read();
		}
		fis.close();
	}
}

package yichang02;
/*
 * try-catch-finally中finally的使用
 * 1.finally是可选的 
 * 2.finally中声明的是一定会被执行的代码,即使catch中又出现异常了,try中有return语句。catch
 *   中有return语句等情况.
 * 3.像数据库的连接、输入输出流、网络连接Socket等资源,JVM是不能自动地回收的,我们需要手动地进行资源的释放。
 *   此时的资源释放工作就得放在finally中
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.junit.Test;

public class FinallyTest {
	@Test
	public void test2() {
		FileInputStream fis=null;
		try {
			File file=new File("hello.txt");
			fis=new FileInputStream(file);
			
			int data = fis.read();
			while(data!=-1) {
				System.out.print((char)data);
				data=fis.read();
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				if(fis!=null)
					fis.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	@Test
	public void methodTest() {
		System.out.println(method());
	}
	public int method() {
		try {
			int[] arr=new int[10];
			System.out.println(arr[10]);
			return 1;
		} catch (ArrayIndexOutOfBoundsException e) {
			// TODO: handle exception
			e.printStackTrace();
			return 2;
		}finally {
			System.out.println("我一定会被执行");  
			return 3;		//会return3
		}
	}
	@Test
	public void test1() {
		try {
			int a=10;
			int b=0;
			System.out.println(a/b);
		} catch (ArithmeticException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			int[] arr=new int[10];
			System.out.println(arr[10]);
		}catch (Exception e) {
			// TODO: handle exception
		}finally {
			System.out.println("xuwenqiangshidashabi");
		}
	}
}

package yichang02;

import java.io.FileNotFoundException;
import java.io.IOException;

/*
 * 方法重写规则一:
 * 子类重写方法抛出的异常类型不大于父类被重写方法抛出的异常类型
 */
public class OverrideTest {
	public static void main(String[] args) {
		OverrideTest ot=new OverrideTest();
		ot.display(new SubClass());
	}
	public void display(SuperClass s) {
		try {
			s.method1();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
class SuperClass{
	public void method1() throws IOException{
		
	}
}
class SubClass extends SuperClass{
	public void method1() throws IOException,FileNotFoundException{   //Exception就不行
		
	}
}

package yichang03;
/*
 * 如何自定义异常类?
 * ① 继承于现有的异常结构:RuntimeException、Exception
 * ② 提供全局常量:serialVersionUID(序列号,相当于类的编号)
 * ③ 提供重载的构造器
 */
public class MyException extends RuntimeException{
	static final long serialVersionUID = -7034897190745766939L;
	public MyException() {
		
	}
	public MyException(String msg) {
		super(msg);
	}
}

package yichang03;

public class StudentTest {
	public static void main(String[] args) {
		try {
			Student s=new Student();
			s.regist(-1001);
			System.out.println(s);
		} catch (Exception e) {
//			e.printStackTrace();
			System.out.println(e.getMessage());
		}
	}
}
class Student{
	private int id;
	public void regist(int id) throws Exception{
		if (id>0) {
			this.id=id;
		}
		else{
//			System.out.println("您输入的数据非法");
			//手动地抛出一个异常对象
//			throw new RuntimeException("您输入的数据非法");
			throw new MyException("您输入的数据非法");
			//错误的
			//throw new String("您输入的数据非法");
		}
	}
	@Override
	public String toString() {
		return "Student [id=" + id + "]";
	}
	
}

练习

package practice;

public class EcDef extends Exception{
	static final long serialVersionUID = -70348745766939L;
	public EcDef() {
		// TODO Auto-generated constructor stub
	}
	public EcDef(String msg) {
		super(msg);
	}
}

package practice;


public class EcmDef {
	public static void main(String[] args) {
		try {
			int i = Integer.parseInt(args[0]);
			int j = Integer.parseInt(args[1]);
			int result=div(i, j);
			System.out.println(result);
		} catch (NumberFormatException e) {
			System.out.println("数据类型不一致");
		} catch (EcDef e) {
			System.out.println(e.getMessage());
		}catch (ArithmeticException e) {
			System.out.println("除0");
		}catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("缺少命令行参数");
		}
	}
	
	public static int div(int i,int j) throws EcDef{
		if (i<0||j<0) {
			throw new EcDef("输入负数异常");
		}else {
			return i/j;
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值