目录
(1)Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源 耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性 的代码进行处理。
(2)Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使 用针对性的代码进行处理。例如: ,空指针访问 ,试图读取不存在的文件 ,网络连接中断 ,数组角标越界
方法重写规则一:子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的类型
6.开发中如何选择使用try-catch-finally还是使用throws?
如何定义异常类? * 1.继承于现有的异常结构,RuntimeException,Exception * 2.提供全局常量serialVersionUID * 3.提供重载的构造器
1.异常概述和异常体系结构
Java程序在执行过程中所发生的异常事件可分为两类:
(1)Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源 耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性 的代码进行处理。
一般不编写针对想代码处理
Error举例
public class ErrorTest {
public static void main(String[] args) {
// 1. 栈溢出:java.lang.StackOverflowError
main(args);
//2.堆溢出: java.lang.OutOfMemoryError: Java heap space
Integer arr[]=new Integer[1024*1024*1024];
}
}
(2)Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使 用针对性的代码进行处理。例如: ,空指针访问 ,试图读取不存在的文件 ,网络连接中断 ,数组角标越界
(3)分类图
红色:编译时异常,蓝色:运行时异常
* java.lang.Throwable
* |-----java.lang.Error:一般不编写针对性的代码处理
* |-----java.lang.Exception:可以进行异常的处理
* |-----编译时异常(checked)
* |-----IOException
* |-----FileNotFoundException
* |-----ClassNotFoundException
* |-----运行时异常(unchecked,RuntimeException)
* |-----NullPointException
* |-----ArrayIndexOutOfBoundsException
* |-----ClassCastException
* |-----NumberMismatchException
* |-----InputMismatchException
* |-----ArithmeticException
2.异常的处理(抓抛模型)
抛:程序执行过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,并将此对象抛出,一旦抛出对象以后,其后的代码就不再执行
关于异常对象的产生:(1)系统自动生成的异常对象 (2)手动的生成一个异常对象,并抛出(throw)
抓:可以理解位异常处理方法:(1) try-catch-finally (2) throws
3. try-catch-finally的使用
格式
try{
* //可能出现异常代码
*
*}catch(异常类型1 变量1){
* //处理异常方式1
*
*}catch(异常类型2 变量2){
* //处理异常方式2
*
*}catch(异常类型3 变量3){
* //处理异常方式3
*}
*.......
*finally{
* //一定会执行的代码
*}
说明:
(1)finally是可选的
(2)使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据次对象的类型,去catch中进行匹配。
(3)一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理,一旦处理完成,就跳出当前的 try-catch结构(没有finally情况下),继续执行气候的代码
(4).catch异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓,catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面,否则报错。
(5)常用方法e.getMessage(),e.printStackTrace();
(6)在try结构中声明的变量,再出了try结构以后,就不能再被调用
(7)使用try-catch-finally处理编译时异常,使得程序再比编译时不报错,但是运行时仍可能报错。相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现
(8)try-catch结构可以嵌套
举例:
@Test
public void test1() {
String str ="123";
str="abc";
try {
int num=Integer.parseInt(str);
System.out.println("Hello1---------1");
}catch (NumberFormatException e) {
System.out.println("格式异常出现异常");
}
System.out.println("Hello2-----------2");
}
运行结果:
格式异常出现异常
Hello2-----------2
@Test
public void test01() {
String str ="123";
str="abc";
try {
int num=Integer.parseInt(str);
System.out.println("Hello1---------1");
}catch(NullPointerException e) {
System.out.println("空指针异常");
}
catch (NumberFormatException e) {
System.out.println("格式异常出现异常");
}catch (Exception e) {
System.out.println("Big Exception");
}
System.out.println("Hello2-----------2");
}
运行结果:
格式异常出现异常
Hello2-----------2
4.finally的使用
举例: 使用finally
@Test
public void test1() {
try {
int a=10;
int b=0;
System.out.println(a/b);
}catch(ArithmeticException e) {
System.out.println("捕获到:ArithmeticException."+":"+e.getMessage());
}catch(Exception e) {
System.out.println("捕获到:Exception."+":"+e.getMessage());
}
// System.out.println("我好帅~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
finally {
System.out.println("我好帅~~~~~~");
}
}
运行结果:
捕获到:ArithmeticException.:/ by zero
我好帅~~~~~~
举例:取消finally
@Test
public void test1() {
try {
int a=10;
int b=0;
System.out.println(a/b);
}catch(ArithmeticException e) {
System.out.println("捕获到:ArithmeticException."+":"+e.getMessage());
}catch(Exception e) {
System.out.println("捕获到:Exception."+":"+e.getMessage());
}
System.out.println("我好帅~~~~~~~~~~~~~~~~~~~~!!!!!");
// finally {
// System.out.println("我好帅~~~~~~");
// }
}
运行结果:
捕获到:ArithmeticException.:/ by zero
我好帅~~~~~~~~~~~~~~~~~~~~!!!!!
举例:catch中有异常,使用finally
public static void main(String[] args) {
try {
int a=10;
int b=0;
System.out.println(a/b);
}catch(ArithmeticException e) {
System.out.println(e.getMessage());
int a[]= new int [10];
System.out.println(a[10]);
}catch(Exception e) {
e.printStackTrace();
}
// System.out.println("我好帅~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
finally {
System.out.println("我好帅~~~~~~");
}
}
运行结果:
/ by zero
我好帅~~~~~~
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at exception.FinallyTest.main(FinallyTest.java:77)
举例:catch中有异常,不使用finally
public static void main(String[] args) {
try {
int a=10;
int b=0;
System.out.println(a/b);
}catch(ArithmeticException e) {
System.out.println(e.getMessage());
int a[]= new int [10];
System.out.println(a[10]);
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("我好帅~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
// finally {
// System.out.println("我好帅~~~~~~");
// }
}
运行结果:
/ by zero
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at exception.FinallyTest.main(FinallyTest.java:77)
举例:捕获异常+finally+return
@Test
public void testMethod() {
int num=method();
System.out.println("num="+num);
}
public int method() {
try {
int a[]=new int [10];
System.out.println(a[20]);
return 1;
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界:"+e.getMessage());
return 2;
}finally {
System.out.println("finally:我一定会被执行");
}
}
运行结果:
数组越界:20
finally:我一定会被执行
num=2
举例:无异常+finally+return
@Test
public void testMethod() {
int num=method();
System.out.println("num="+num);
}
public int method() {
try {
int a[]=new int [10];
// System.out.println(a[20]);
return 1;
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界:"+e.getMessage());
return 2;
}finally {
System.out.println("finally:我一定会被执行");
}
}
运行结果:
finally:我一定会被执行
num=1
举例:fnally中有return
@Test
public void testMethod() {
int num=method();
System.out.println("num="+num);
}
public int method() {
try {
int a[]=new int [10];
System.out.println(a[20]);
return 1;
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界:"+e.getMessage());
return 2;
}finally {
System.out.println("finally:我一定会被执行");
return 3;
}
}
运行结果:
数组越界:20
finally:我一定会被执行
num=3
5.异常处理二:throws+异常类型
(1)throws+类型 写在方法的声明处。指明此方法执行时,可能回抛出的异常类型。
一旦当方法体执行时,出现异常,仍会在异常处生成一个异常类的对象,此对象满足throws后异常类型时,就会被抛出。异常代码后续的代码,就不再执行
(2)2.try-catch-finally:真正的将异常处理了。throws 的方法只是将异常抛给了方法的调用者,并没有真正将异常处理掉。
举例:throws抛异常:
public static void Method2() throws IOException{
Method1();
}
public static void Method1() throws FileNotFoundException,IOException{
File file=new File("date1.txt");
FileInputStream fis=new FileInputStream(file);
int data=fis.read();
while(data!=-1) {
System.out.println(data);
data=fis.read();
}
fis.close();
System.out.println("hahahahha");
}
public static void main(String[] args) {
try {
Method2();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
方法重写规则一:
子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的类型
补充:假如父类的某个方法没有抛异常,那么子类在 重写这个方法的时候,也不能抛异常
public class OverrideTest {
public static void main(String[] args) {
OverrideTest test=new OverrideTest();
test.display(new SubClass());
}
private void display(SuperClass s) {
try {
s.method();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class SuperClass{
public void method() throws IOException{
}
}
class SubClass extends SuperClass{
public void method() throws FileNotFoundException{
}
}
6.开发中如何选择使用try-catch-finally还是使用throws?
(1) 如果父类中被重写的方法没有throws方法处理异常,则子类重写的方法也不能使用throws,意味着如果子类重写的方法中有异常,必须使用try-catch-finally方式处理。
(2)执行的方法a中,先后又调用了另外的几个方法,这几个方法都是递进关系执行的。我们建议这几个方法使用throws方式进行处理。而执行的方法a可以考虑使用try-catch-finally方式进行处理。
7.手动抛出异常
举例:抛出普通的RuntimeException。
regist方法不用throws,调用regist的main方法不同,try-catch处理
public class StudentTest {
public static void main(String[] args) {
Student s=new Student();
s.regist(-1001);
System.out.println(s.id);
}
}
class Student{
int id;
public void regist(int id) {
if(id>0) {
this.id=id;
}else {
//手动抛出异常
//这种不用try-catch
throw new RuntimeException("你输入的数据非法");
}
}
}
举例:抛出Exception
regist方法要throws抛出异常,调用regist的main要处理异常
public class StudentTest {
public static void main(String[] args) {
Student s=new Student();
try {
s.regist(-1001);
System.out.println(s.id);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
class Student{
int id;
public void regist(int id) throws Exception {
if(id>0) {
this.id=id;
}else {
//手动抛出异常
//这种不用try-catch
// throw new RuntimeException("你输入的数据非法");
throw new Exception("你输入的数据非法");
// throw new MyException("不能输入负数");
}
}
}
8.用户自定义异常
如何定义异常类?
* 1.继承于现有的异常结构,RuntimeException,Exception
* 2.提供全局常量serialVersionUID
* 3.提供重载的构造器
public class MyException extends RuntimeException{
static final long serialVersionUID = -7034897190745766939L;
public MyException(){
}
public MyException(String msg) {
super(msg);
}
}
抛出MyException
public class StudentTest {
public static void main(String[] args) {
Student s=new Student();
try {
s.regist(-1001);
System.out.println(s.id);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
class Student{
int id;
public void regist(int id) throws Exception {
if(id>0) {
this.id=id;
}else {
//手动抛出异常
//这种不用try-catch
// throw new RuntimeException("你输入的数据非法");
// throw new Exception("你输入的数据非法");
throw new MyException("不能输入负数");
}
}
}