[Java 进阶]异常

异常:程序在运行过程中发生由于硬件设备问题、软件设计错误等导致的程序异常事件。 世上没有百分之百完美的程序。程序总难免存在各式各样的问题。所以,程序中添加对于错误的处理机制是十分有必要的。这就好比人多的公共场所需要有防火防盗的安保系统一个道理。

捕获异常

异常处理格式

try {
 // 有可能出现异常的语句
 } catch (Type1 e1) {
 // 异常类型1处理代码
 } catch (Type2 e2) {
 // 异常类型2处理代码
 } 
 // etc...
 catch (TypeN en) {
 // 异常类型n处理代码
 } finally {
 // 不管有没有发生异常,finally语句块都会被执行
 // 在 try...catch 异常处理机制中, finally关键字是可选的
 }

try 关键字之后的程序块就是异常的监控区域

多个 catch 关键字后面的程序块,则是针对每个要捕获的异常,所准备的相应处理程序。

finally 关键字之后的程序块,无论是否出现异常,总会被执行。 finally 关键字在 try...catch 机制中并不是必须的。

public class ExceptionDemo02 {
 public static void main(String args[]) {
         System.out.println("********** 计算开始 ***********");
 int i = 10;
 int j = 0;
 try {
 int temp = i / j; // 此处产生了异常
             System.out.println("两个数字相除的结果:" + temp);
             System.out.println("****************************");
         } catch (ArithmeticException e) {
             System.out.println("出现异常了:" + e);
         } finally {
             System.out.println("对与不对,我都在这里,不偏不移");
         }        
         System.out.println("********** 计算结束 ***********");
     }
 };

自定义异常

JAVA虽然提供了大量的异常类,但也不可能预见所有的异常情况。所以可以自己定义异常类来表示程序可能会遇到的特定问题。

要自定义异常类,必须从已有的异常类继承,最好选择功能相近的异常类继承。

// 自定义异常类,继承Exception类
 class MyException extends Exception {
 public MyException(String msg) {
 super(msg); // 调用Exception类中有一个参数的构造方法,传递错误信息
     }
 };
 
 public class DefaultException {
 public static void main(String args[]) {
 try {
 throw new MyException("自定义异常。"); // 抛出异常
         } catch (Exception e) {
             e.printStackTrace();
         }
     } /* Output:
 MyException: 自定义异常。
     at DefaultException.main(DefaultException.java:11)
 */
 }

抛出异常

在定义一个方法时可以使用 throws 关键字声明,使用 throws 声明的方法表示此方法不处理异常,而交给方法的调用处进行处理。

public 返回值类型 方法名称(参数列表...) throws  异常类{}

需要注意的是,如果异常类类型不是运行时异常类型,那么在调用这个方法时,不管是否有问题,都必须使用 try...catch 进行异常的捕获与处理。

class Div {
 // 定义除法操作,如果有异常,则交给被调用处处理
  public int div(int i, int j) throws Exception {
 int temp = i / j;
 return temp;
     }
 };
 
 public class ThrowsDemo01 {
 public static void main(String args[]) {
         Div div = new Div();
 // div.div(10, 0); // 如果不使用 try...catch 结构,编译器会认为出错
  try {
             System.out.println("除法操作:" + div.div(10, 0));
         } catch (Exception e) {
             e.printStackTrace(); // 打印异常
         }
     }
 };

throws 不同,throw 关键字表示主动地抛出一个异常,抛出时直接抛出异常类的实例化对象即可。

public class ThrowDemo01{
 public static void main(String args[]){
 try{
 throw new Exception("自己抛着玩的。") ;    // 抛出异常的实例化对象
        }catch(Exception e){
            System.out.println(e) ;
        }
    }
};

异常的类型

JAVA中所有的异常类都继承自 Throwable 类。

异常可分为两大类:Exception 和 Error。

Exception:一般指的是程序中出现的问题,可以通过 try...catch 处理。

Error:一般指的是JVM错误,程序无法处理。

Exception还可以再继续细分为运行时异常(RuntimeException)非运行时异常

运行时异常可以不使用 try...catch 进行处理。

非运行时异常必须使用 try...catch 进行处理。

请看以下代码:

public class RuntimeExceptionDemo01 {
 public static void main(String args[]) {
 int result = 0;
         String str = "10";
         String str2 = "abc";
         result = Integer.parseInt(str); // 将字符串中的数字转为int类型
         System.out.println(result * result);
         result = Integer.parseInt(str2); // 试图将字符串中字母转为int类型时会出现异常
         System.out.println(result * result);
     }
 };

执行以上代码时,再第二次调用Integer.parseIn()时会出现异常。我们看一下这个方法的定义:

public static int parseInt(String s) throws NumberFormatException

这里使用了 throws 关键字,但是在实际调用时并没有使用 try...catch,编译器也没有报错。

这是因为所有继承自 RuntimeException 的类都可以不使用 try...catch 进行处理。在这种情况下,如果产生异常,将由 JVM 进行处理,此时肯定会中断程序。

所以,如果想要程序在出错时仍可以继续执行,最好还是使用 try...catch 的异常处理机制来处理。

参考资料

Java 编程思想

JAVA 开发实战宝典

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构沉思录

Java虚拟机内存初探

Java 程序的执行过程:Java 源代码文件(.Java文件)-> Java Compiler(Java编译器)->Java 字节码文件(.class文件)-...

1172
来自专栏Java编程

Java虚拟机体系结构

一个运行时的Java虚拟机实例的天职是:负责运行一个java程序。当启动一个Java程序时,一个虚拟机实例也就诞生了。当该程序关闭退出,这个虚拟机实例也就随之消...

7221
来自专栏菜鸟致敬

【Lua菜鸟②】数据类型

Lua是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。(我想了想python) -- 用来单行注释 --[[...

3796
来自专栏Script Boy (CN-SIMO)

突如其来的"中断异常",我(Java)该如何处理?

一、何为异常? 1.生活中的实例 生活中存在许多不正常: 上班路上自行车掉链子 上厕所手机掉马桶 下班回家钥匙丢失 。。。。。。。 2.程序中的实...

2200
来自专栏顶级程序员

谈谈 Python 的生成器

第一次看到Python代码中出现yield关键字时,一脸懵逼,完全理解不了这个。网上查下解释,函数中出现了yield关键字,则调用该函数时会返回一个生成器。那到...

3376
来自专栏java学习

工程师笔试题1(答案解析)

1.访问修饰符作用范围由大到小是( )。 A.private-protected-default-publicB.public-protected-defaul...

2515
来自专栏大闲人柴毛毛

深入理解JVM(二)——揭开HotSpot对象创建的奥秘

对象的创建过程 当虚拟机遇到一条含有new的指令时,会进行一系列对象创建的操作: 检查常量池中是否有即将要创建的这个对象所属的类的符号引用; 若常量池中没...

3438
来自专栏技术博客

设计模式之一(单例模式)

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。

622
来自专栏静默虚空的博客

[设计模式]原型模式

简介 原型模式 (Prototype)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 原型模式是一种对象创建型模式 (可参考 设计模式 创建型...

1828
来自专栏desperate633

设计模式之单件模式(Singleton Pattern)引出单例模式经典单例模式的实现定义单件模式经典单件模式存在的问题解决单例模式的多线程问题

单件模式,也叫单例模式,可以说是设计模式中最简单的一种。顾名思义,就是创造独一无二的唯一的一个实例化的对象。

823

扫码关注云+社区