`
diaolanshan
  • 浏览: 175139 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

浅析Java语言中两种异常的差别

    博客分类:
  • JAVA
阅读更多

Java提供了两类主要的异常:runtime exception和checked exception。所有的checked exception是从java.lang.Exception类衍生出来的,而runtime exception则是从java.lang.RuntimeException或java.lang.Error类衍生出来的。 

  它们的不同之处表现在两方面:机制上和逻辑上。 
  一、机制上 

  它们在机制上的不同表现在两点:1.如何定义方法;2. 如何处理抛出的异常。请看下面CheckedException的定义: 

  public class CheckedException extends Exception 
  { 

  public CheckedException() {} 
  public CheckedException( String message ) 
  { 
  super( message ); 
  } 
  } 

  以及一个使用exception的例子: 

  public class ExceptionalClass 
  { 

  public void method1() 
  throws CheckedException 
  { 
   // ... throw new CheckedException( “...出错了“ ); 
  } 
  public void method2( String arg ) 
  { 
   if( arg == null ) 
   { 
    throw new NullPointerException( “method2的参数arg是null!” ); 
   } 
  } 
  public void method3() throws CheckedException 
  { 
   method1(); 
  } 
  } 

  你可能已经注意到了,两个方法method1()和method2()都会抛出exception,可是只有method1()做了声明。另外,method3()本身并不会抛出exception,可是它却声明会抛出CheckedException。在向你解释之前,让我们先来看看这个类的main()方法: 

  public static void main( String[] args ) 
  { 

  ExceptionalClass example = new ExceptionalClass(); 
  try 
  { 
  example.method1(); 
  example.method3(); 
  } 
  catch( CheckedException ex ) { } example.method2( null ); 
  } 

  在main()方法中,如果要调用method1(),你必须把这个调用放在try/catch程序块当中,因为它会抛出Checked exception。 

  相比之下,当你调用method2()时,则不需要把它放在try/catch程序块当中,因为它会抛出的exception不是checked exception,而是runtime exception。会抛出runtime exception的方法在定义时不必声明它会抛出exception。 

  现在,让我们再来看看method3()。它调用了method1()却没有把这个调用放在try/catch程序块当中。它是通过声明它会抛出method1()会抛出的exception来避免这样做的。它没有捕获这个exception,而是把它传递下去。实际上main()方法也可以这样做,通过声明它会抛出Checked exception来避免使用try/catch程序块(当然我们反对这种做法)。 

  小结一下: 

  * Runtime exceptions: 

  在定义方法时不需要声明会抛出runtime exception; 

  在调用这个方法时不需要捕获这个runtime exception; 

  runtime exception是从java.lang.RuntimeException或java.lang.Error类衍生出来的。 

  * Checked exceptions: 

  定义方法时必须声明所有可能会抛出的checked exception; 

  在调用这个方法时,必须捕获它的checked exception,不然就得把它的exception传递下去; 

  checked exception是从java.lang.Exception类衍生出来的。 


  二、逻辑上 

  从逻辑的角度来说,checked exceptions和runtime exception是有不同的使用目的的。checked exception用来指示一种调用方能够直接处理的异常情况。而runtime exception则用来指示一种调用方本身无法处理或恢复的程序错误。 

  checked exception迫使你捕获它并处理这种异常情况。以java.net.URL类的构建器(constructor)为例,它的每一个构建器都会抛出MalformedURLException。MalformedURLException就是一种checked exception。设想一下,你有一个简单的程序,用来提示用户输入一个URL,然后通过这个URL去下载一个网页。如果用户输入的URL有错误,构建器就会抛出一个exception。既然这个exception是checked exception,你的程序就可以捕获它并正确处理:比如说提示用户重新输入。 

  再看下面这个例子: 

  public void method() 
  { 

  int [] numbers = { 1, 2, 3 }; 
  int sum = numbers[0] numbers[3]; 
  } 

  在运行方法method()时会遇到ArrayIndexOutOfBoundsException(因为数组numbers的成员是从0到2)。对于这个异常,调用方无法处理/纠正。这个方法method()和上面的method2()一样,都是runtime exception的情形。上面我已经提到,runtime exception用来指示一种调用方本身无法处理/恢复的程序错误。而程序错误通常是无法在运行过程中处理的,必须改正程序代码。 

  总而言之,在程序的运行过程中一个checked exception被抛出的时候,只有能够适当处理这个异常的调用方才应该用try/catch来捕获它。而对于runtime exception,则不应当在程序中捕获它。如果你要捕获它的话,你就会冒这样一个风险:程序代码的错误(bug)被掩盖在运行当中无法被察觉。因为在程序测试过程中,系统打印出来的调用堆栈路径(StackTrace)往往使你更快找到并修改代码中的错误。有些程序员建议捕获runtime exception并纪录在log中,我反对这样做。这样做的坏处是你必须通过浏览log来找出问题,而用来测试程序的测试系统(比如Unit Test)却无法直接捕获问题并报告出来。 

  在程序中捕获runtime exception还会带来更多的问题:要捕获哪些runtime exception?什么时候捕获?runtime exception是不需要声明的,你怎样知道有没有runtime exception要捕获?你想看到在程序中每一次调用方法时,都使用try/catch程序块吗?

 

分享到:
评论

相关推荐

    浅析Java语言中线程的生命周期及实现方式.pdf

    浅析Java语言中线程的生命周期及实现方式 Java语言中的线程(Thread)是指在同一个进程中可以并发执行的多个控制流程。线程是Java语言中定义的非常重要的基本概念和技术标准。随着整个社会信息化的发展,传统服务器...

    浅析JAVA与C++的区别.pdf

    "浅析JAVA与C++的区别" Java和C++是两种最流行的程序设计语言,它们之间有很多的相似之处,但同时也存在很多的区别。下面我们将从技术角度对这两种语言的区别进行分析。 一、继承 C++支持类的多继承,而Java采用...

    浅析页面中Java与JavaScript脚本的区别.pdf

    Java 与 JavaScript 脚本是两种不同的编程语言,它们在 Web 开发中扮演着重要的角色。虽然它们都可以嵌入到 HTML 页面中,但是它们的表示方式、执行过程和应用场景都是不一样的。 首先,我们来看看 Java 脚本。...

    浅析面向对象语言C_与Java区别_王艳娟1

    在面向对象编程领域,C++和Java是最典型且广泛使用的两种语言。了解它们之间的差异对于软件开发人员至关重要。 面向对象(Object-Oriented, OO)是当今计算机科学的核心,90年代以来已成为软件开发的主流范式。它的...

    浅析Java抽象类与接口的区别.pdf

    在Java编程语言中,抽象类和接口是两种面向对象编程(OOP)机制,用以实现抽象概念的不同方式。理解这两者之间的区别对于掌握Java的面向对象特性至关重要,尤其在设计软件架构时。以下将详细分析Java中抽象类和接口...

    浅析Java抽象类与接口的区别.zip

    在Java编程语言中,抽象类和接口是两种重要的面向对象设计概念,它们都用于实现多态性,但各自具有不同的特点和应用场景。本篇文章将详细分析这两种机制的区别,以帮助开发者更好地理解和运用。 首先,抽象类是类的...

    Java中堆内存与栈内存分配浅析

    ### Java中堆内存与栈内存分配浅析 #### 一、引言 在Java编程语言中,内存管理是一项至关重要的技术。程序运行时所使用的内存主要分为两类:堆内存(Heap Memory)和栈内存(Stack Memory)。理解这两种内存类型的...

    Java NIO:浅析IO模型_动力节点Java学院整理

    Java NIO是Java语言中用于高性能I/O操作的API,理解IO模型是学习Java NIO的基础。本文将从同步和异步的概念开始,然后介绍阻塞和非阻塞的区别,接着介绍阻塞IO和非阻塞IO的区别,最后介绍五种IO模型和两种高性能IO...

    浅析Java中Runnable和Thread的区别

    在Java编程语言中,创建和管理多线程有两种主要的方式:继承`Thread`类和实现`Runnable`接口。这两种方式都是为了实现并发执行任务,但它们之间存在一些关键的区别。 首先,当我们创建一个新的线程时,实际上是为了...

    浅析JAVA之垃圾回收机制.doc

    在Java编程中,与C++或C等语言相比,开发者无需手动管理内存,因为Java引入了一种自动的内存管理机制——垃圾回收(Garbage Collection,简称GC)。垃圾回收器负责监测并回收不再使用的对象所占用的内存空间,以防止...

    浅析Java中String与StringBuffer拼接的区别

    在Java编程语言中,String和StringBuffer类都用于处理字符串,但它们在处理字符串拼接时有着显著的区别。本文将详细解析这两个类在拼接字符串时的行为差异。 首先,我们来了解一下String类。String对象在Java中是不...

    浅谈java面向对象和引用

    Java中的多态可以通过覆盖和重载两种方式实现。 #### Java中的引用详解 在Java中,对象是通过引用(Reference)来访问的。引用是指向对象的一个指针,而不是对象本身。理解引用的概念对于深入掌握Java非常重要。 ...

    Java 集合浅析.txt

    Java集合框架是Java编程语言中处理数据结构的一个强大工具包,它提供了一系列灵活高效的接口和实现来帮助开发者管理数据。本篇文章将重点介绍Java中常用的集合类——`Collection`和`Map`及其相关子类,并探讨它们...

    浅析Java中的继承与组合

    在Java编程语言中,继承和组合是两种主要的面向对象设计原则,它们分别代表了类之间的不同关系。本文将深入探讨这两个概念以及它们在实际编程中的应用和选择。 首先,让我们了解一下继承。继承是Java中一种强大的...

    浅析C语言、Java、Python的数组合并方法.pdf

    C语言、Java和Python这三种编程语言虽然在数组合并的方法上有所差异,但它们都为数组合并操作提供了相对便捷的方式。以下是这些语言在数组合并方面的详细知识点: C语言数组合并: 在C语言中,由于语言的低级特性,...

    浅析Java中comparator接口与Comparable接口的区别

    在Java编程语言中,Comparable和Comparator接口都用于比较对象,但它们之间存在一些关键区别,这对于理解和优化代码的可扩展性至关重要。 首先,Comparable接口是一个排序接口,它定义了一个单一的方法`compareTo(T...

    浅析Java 对象引用和对象本身

    例如,在上述示例的for循环中,我们看到两种不同的操作方式: 1. **方法入参**:在方法中通过对象引用参数修改对象属性,如: ```java void updateUser(User user) { user.setName("newName"); } ``` 这会...

    浅析Java中局部变量与成员变量同名解决技巧

    Java编程语言中,变量是程序的基本构建块,用于存储数据。根据它们的作用域和生命周期,变量分为两类:成员变量和局部变量。理解这两者的区别对于编写清晰、有效的Java代码至关重要。 成员变量,也称为实例变量,是...

    浅析BBS与blog的区别

    BBS(Bulletin Board System,电子公告牌)和 Blog 是两种不同的网络应用,虽然它们都提供了信息共享和交流的平台,但它们在许多方面存在着明显的区别。 1.适用范围不同 BBS 是一个开放的、自由的空间,面向的是一...

    Java程序与C语言的区别浅析

    Java 和 C 语言是两种广泛使用的编程语言,它们在设计理念、特性和应用上存在显著的差异。虽然两者都属于高级编程语言,但它们的核心特点和使用场景有所不同。 首先,Java 是一种面向对象的语言,它的设计目标是...

Global site tag (gtag.js) - Google Analytics