目录
1.异常的概念与体系结构
1.1异常的体系结构
![](https://i-blog.csdnimg.cn/blog_migrate/49794de3565da4d9916ac04dd685c411.png)
从上图中可以看到:
1. Throwable : 是异常体系的顶层类,其派生出两个重要的子类 , Error 和 Exception2. Error : 指的是 Java 虚拟机无法解决的严重问题,比如: JVM 的内部错误、资源耗尽等 ,典型代表: StackOverflflowError 和 OutOfMemoryError ,一旦发生回力乏术。3. Exception : 异常产生后程序员可以通过代码进行处理,使程序继续执行。比如:感冒、发烧。我们平时所说 的异常就是Exception 。
1.2异常的举例
public static void main(String[] args) {
System.out.println(10/0);
}
运行结果及分析:
补充:
(2)数组越界异常
public static void main(String[] args) {
int[] arr = {1, 2, 3,4,5};
System.out.println(arr[10]);
}
public static void main(String[] args) {
int[] arr = null;
System.out.println(arr.length);
}
1.3错误的举例
StackOverflflowError
public class Text2 {
public static void fun(){
fun();
}
public static void main(String[] args) {
fun();
}
}
执行结果:
2.异常的分类
2.1编译时异常
![](https://i-blog.csdnimg.cn/blog_migrate/bca17fd59bbedd6683b9c2e36836b5ac.png)
理解:
![](https://i-blog.csdnimg.cn/blog_migrate/95142fb4331ba2b7f6a58279e0e096a5.png)
正确完整代码:
public class Text3 {
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person(18, "WH");
Person p2= (Person) p1.clone();
}
}
public class Person {
int age;
String nume;
public Person(int age, String nume) {
this.age = age;
this.nume = nume;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
2.2运行时异常
3.异常的处理
在Java中,异常处理主要的5个关键字:try、catch、final、throw、throws。
![](https://i-blog.csdnimg.cn/blog_migrate/cd3c08f399dbd91c9d212a0e363e09d1.png)
3.1异常的抛出throw
throw new XXXException ( " 异常产生的原因 " )
![](https://i-blog.csdnimg.cn/blog_migrate/c3e9aea0bae0ebd76ea12cd18cdef39b.png)
运行结果:
Exception in thread "main" java.lang.NullPointerException: hahaha
(1) throw 必须写在方法体内部(2)抛出的对象必须是 Exception 或者 Exception 的子类对象(3) 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处 理, 直接交给JVM来处理(4)如果抛出的是编译时异常,用户必须处理,否则无法通过编译(5)异常一旦抛出,其后的代码就不会执行
对于(3)(5)举例:
![](https://i-blog.csdnimg.cn/blog_migrate/cad6dfb7559a2ed252a6718178cc81bd.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4c867b452d421d190926a6c3d9a261bc.png)
3.2try-catch捕获并处理
语法形式:
public static void main(String[] args) {
try{
System.out.println(10/0);
System.out.println(100);
}catch (ArithmeticException e){
e.printStackTrace();
}
}
运行结果:
java.lang.ArithmeticException: / by zero
(2)如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到 JVM收到后中断程序----异常是按照类型来捕获的
public static void main(String[] args) {
try {
System.out.println(10/0);
} catch (NullPointerException e) {
System.out.println(10);
}
}
运行结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
![](https://i-blog.csdnimg.cn/blog_migrate/c1dec6b51ed0559809d8273a0ed4dbc4.png)
(4)如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch,否则语法错误
(5)可以通过一个catch捕获所有的异常,即多个异常,一次捕获(不推荐)
3.3finally
![](https://i-blog.csdnimg.cn/blog_migrate/d2a4e0eac8308cab53882a1d46759419.png)
finally 执行的时机是在方法返回之前 (try 或者 catch 中如果有 return 会在这个 return 之前执行 fifinally). 但是如果 finally 中也存在 return 语句 , 那么就会执行 fifinally 中的 return, 从而不会执行到 try 中原有的 return.一般我们不建议在 finally 中写 return ( 被编译器当做一个警告 )
3.4 异常声明throws
语法格式:
修饰符 返回值类型 方法名 ( 参数列表 ) throws 异常类型 1 ,异常类型 2 ...{}注意:
如果方法是main方法调用者仍然可以不处理异常,借助throws将异常抛 给JVM来处理。
1. throws 必须跟在方法的参数列表之后2. 声明的异常必须是 Exception 或者 Exception 的子类3. 方法内部如果抛出了多个异常, throws 之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型 具有父子关系,直接声明父类即可。4.我们在使用throws时,要明确声明的异常是编译时异常还是运行时异常。
比如:
(1)
(2)
如果是 运行时异常调用者不处理异常也没关系,JVM会处理。
但如果是编译时异常一定要处理异常
处理方式:(1)try-catch捕获并处理
(2)借助throws将异常抛 给JVM来处理。
4.自定义异常类
![](https://i-blog.csdnimg.cn/blog_migrate/26fda2f97d3a6e2074eab192d7dbdd56.png)
定义Course类,Course包含private String cno,private String cname,private int credit,Course包括方法:public Course(),public Course。Define CreditException类扩展(继承) 在RunTimeException中,CreditException包含以下方法:public CreditException()、public CreditException(String Message)。
如果课程的学分低于0.5或高于6,则课程的构建方法将抛出CreditException,消息为“学分应在0.5和6之间!”。
定义公共类TestCourse,创建一个Course对象,并使用try/catch块来处理CreditException。
import java.util.Scanner;
public class LogIn {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入cno");
String cno=scanner.next();
System.out.println("请输入课程名字");
String cname=scanner.next();
System.out.println("请输入学分");
double credit=scanner.nextDouble();
Course course=new Course(cno,cname,credit);
try {
if(!(course.getCredit()>=0.5&&course.getCredit()<=6)){
throw new CreditException("课程的学分应在0.5到6之间");
}else{
System.out.println("输入成功学分为:"+course.getCredit());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Course{
private String cno;
private String cname;
private double credit;
public Course(String cno, String cname, double credit) {
this.cno = cno;
this.cname = cname;
this.credit = credit;
}
public Course() {
}
public String getCno() {
return cno;
}
public void setCno(String cno) {
this.cno = cno;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public double getCredit() {
return credit;
}
public void setCredit(double credit) {
this.credit = credit;
}
}
class CreditException extends RuntimeException{
public CreditException(String message){
super(message);
}
}
注意事项
- 自定义异常通常会继承自 Exception 或者 RuntimeException
- 继承自 Exception 的异常默认是受查异常
- 继承自 RuntimeException 的异常默认是非受查异常
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞