`

“Java异常Exception”总结

    博客分类:
  • java
阅读更多
1. 异常(Exception)。
2. Java中的异常分为两大类:
a) Checked exception  (非  Runtime Exception) 非运行时异常
b) Unchecked exception(Runtime Exception) 运行时异常
3. Java中所有的异常类都会直接或间接地继承自Exception。
4. RuntimeException类也是直接继承自Exception类,它叫做运行时异常,Java中所有
的运行时异常都会直接或间接地继承自RuntimeException。
5. Java 中凡是继承自Exception而不是继承自RuntimeException的类都是非运行时异
常。 如附件图:运行—非运行异常区分.jpg

6.异常处理的一般结构是:
try
{
}
catch(Exception e)
{
}
finally
{
}
无论程序是否出现异常,finally 块中的代码都是会被执行的。
7. 对于非运行时异常(checked  exception),必须要对其进行处理,处理方式有两种:
第一种是使用try.. catch…finally 进行捕获;第二种是在调用该会产生异常的方法所在
的方法声明throws Exception 继续往外抛。
8. 对于运行时异常(runtime  exception),我们可以不对其进行处理,也可以对其进行处理。推荐不对其进行处理。
9. NullPointerException是空指针异常,出现该异常的原因在于某个引用为null,但你却调用了它的某个方法。这时就会出现该异常。

10.Error和Exception之间关系:程序可能会发生错误Error,可能会出现异常Exception。异常是我们可以处理的情况,但是如果程序发生了错误,我们就不能处理了。错误的危险级别比异常更高。一般情况下如果我们在代码上不做任何处理的话,程序发生了异常,那么异常代码后面的代码就不会再去执行了,但是如果我们对异常代码提前做了相应的处理(比如抛出或捕获),那么当异常发生的时候,代码还是能够继续往下执行的;而对于错误Error,我们无能为力,没有办法做任何处理,也没有任何办法让错误代码下面的代码继续执行。

系统对于运行时异常和非运行时异常的处理方式是完全不一样的。


Java里面每一个异常都是一个类,当程序执行到某一行如果出现异常的话,它会在可能产生异常的这一行代码的位置处产生一个针对于这个异常的一个异常对象(至于是哪个异常类型的对象,它会根据实际的异常情况自己去选择),这个对象是由它运行的时候来去动态的去生成的。如下代码:
Int c = 0;
Try {
Int a = 3;
Int b = 0;
C = a / b;
} catch (ArithmeticException e) {
e.printStrackTrace();
}
如果出现异常,会生成一个异常类对象,这个对象直接赋给引用变量e。


注意:在try块里面,如果某行代码出现异常了,那么流程会直接从这行代码转到catch块里面,try块里面此行代码后面的代码不会再去执行了。Catch块完了之后再往后正常去执行catch块后面的代码。


可能发生异常的代码放到try里面。一定要执行的代码放到finally里面。

程序光有try和finally,没有catch也是可以的。也是可以正常编译通过的。这样就相当于没有对异常进行处理,和不加try、catch是一个效果,后面的代码不会再去执行。
一个try后面不论跟着多少个catch,最多只会有一个catch被执行。


在一个方法里面我们可以自己手工的去抛出异常,用关键字throw,抛出的是异常对象(异常出现的时候产生的也是异常对象)。如下代码作解释:
package com.shengsiyuan.exception;

public class ExceptionTest2 {
	public void method() throws Exception {
		System.out.println("hello world");

		// 当流程执行到这行代码的时候,我们是让这个方法抛出一个异常,所以这里要new出来一个异常对象,把它抛出来,所有的异常实际上都是对象。
		// 这里我们手动抛出的异常对象和假如实际开发中这行代码出现异常程序会自动帮助我们生成一个异常对象然后抛出来这两种情况是类似的,都是生成异常对象然后抛出。这里只是总结的一个示例。
		// 这行代码抛出了异常,那么在方法申明的时候也要把这个异常抛出去(throws
		// Exception),告诉调用这个方法的其他方法我的这个方法会抛出异常。方法里里面和方法声明时抛出异常用的关键字不同。
		throw new Exception();
	}
}




所有的异常实际上都是对象。


异常的第一种方式是try  catch捕获,第二种方式是抛出异常,抛出异常是由调用这个方法的那个方法对这个异常进行处理,它的处理方式也是有两种,要么捕获,要么继续抛出,继续抛给调用它的方法,就这样一层一层的网上抛。最后,main方法是我们的最后一个方法,如果main方法我们也声明为抛出的方式,那么最后异常就会抛给Java虚拟机了,由虚拟机自己去处理。

真正抛出异常对象的地方都是在程序代码里面,比如某行代码出异常了,程序会自动的生成一个相应的异常对象然后抛出,也可能是我们在代码里面某些地方自己手动的抛出异常对象,这个也是先new出来一个相应的异常对象,然后抛出(throw);而在方法声明的时候写的比如throws Exception,它不是真正的抛出异常对象,而只是做出一个声明,声明我的这个方法有可能会抛出异常,同样的也告诉调用这个方法的调用端我的这个方法有可能会抛出异常,调用端你也同样的需要做好抛出异常的准备(调用端方法声明中声明throws Exception)。就这样你调用我,他调用你,你把我这里抛出的异常继续往上抛,他把你这里出来的异常也继续往上抛,就这样一层层的,一直往上抛,最后把异常抛给了Throwable,由它来处理。

一、可查异常和不可查异常
通常,Java的异常(包括Exception和Error)分为可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。
可查异常(编译器要求必须处置的异常):正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。
除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
不可查异常(编译器不要求强制处置的异常):包括运行时异常(RuntimeException与其子类)和错误(Error)。
如果使用throw在方法体中抛出可查异常,则需要在方法头部声明方法可能抛出的异常类型。程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。

二、运行时异常和非运行时异常
(1)运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
当出现RuntimeException的时候,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。
出现运行时异常后,如果没有捕获处理这个异常(即没有catch),系统会把异常一直往上层抛,一直到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
如果不想终止,则必须捕获所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。

(2)非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。如IOException、SQLException等以及用户自定义的Exception异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch并处理,否则程序就不能编译通过。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。

常见RuntimeException:
ArrayStoreException                试图将错误类型的对象存储到一个对象数组时抛出的异常
ClassCastException                试图将对象强制转换为不是实例的子类时,抛出该异常
IllegalArgumentException         抛出的异常表明向方法传递了一个不合法或不正确的参数
IndexOutOfBoundsException   指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出
NoSuchElementException       表明枚举中没有更多的元素
NullPointerException                当应用程序试图在需要对象的地方使用 null 时,抛出该异常


下面讲解自定义异常:

所谓自定义异常,通常就是定义了一个继承自Exception类的子类,那么这个类就是一个自定义异常类。通常情况下,我们都会直接继承自Exception类,一般不会继承某个运行时的异常类。

自定义异常本身非常简单,不难,但是在实际开发里面几乎每个项目或多或少都会用到自定义异常,比如说你做了一件事情,比如用户在登录或是什么时候,用户名或密码错了之类的,遇到这些情况一方面是可以通过判断(if...else…),另外一方面也可以通过抛异常的方式处理。

自定义异常类都需要继承Exception类。

异常2中处理方式的比较:采用抛出的方式,程序一旦出现异常就一定不会再往下继续执行了;而采用try…catch…方式,程序一旦出现异常还是可以继续往下执行。

下面是一个自定义异常的实例(重点掌握):
package com.shengsiyuan.exception;

/**
 * 自定义异常
 * 自定义异常类都需要继承Exception类。
 * 自定义异常一般都有两个构造方法,一个不带参数的空的构造方法,一个接收一个字符串参数的构造方法。
 * 类: MyException <br>
 * 描述: TODO <br>
 * 作者: 
 * 时间: Oct 30, 2013 11:02:15 AM
 */
public class MyException extends Exception {
	public MyException() {
		super();
	}

	// 这个方法接收的参数message一般为异常发生时的提示信息。
	public MyException(String message) {
		// 调用父类Throwable里面接收一个字符串参数的构造方法,它会把这个message的值赋给Throwable里面的detailMessage变量,detailMessage这个变量一般就是Throwable类在处理异常时(因为大多数异常最后都是抛给了它,由它来统一处理,当然,利用try...catch...捕获除外。要么最后抛出到Throwable处理,要么捕获处理)给出的提示信息。
		super(message);
	}
}

package com.shengsiyuan.exception;

/**
 * 自定义异常使用示例
 * 类: ExceptionTest4 <br>
 * 描述: TODO <br>
 * 作者: 
 * 时间: Oct 30, 2013 11:52:47 AM
 */
public class ExceptionTest4 {
	public void method(String str) throws MyException {
		if (null == str) {
			// 抛出异常对象,一层层随着方法之间的调用往上抛,一直到最后抛给Throwable来处理该异常
			throw new MyException("传入的字符串参数不能为null");
		} else {
			System.out.println(str);
		}
	}

	/**
	 * 演示异常的两种处理方式
	 * 方法: main <br>
	 * 描述: TODO <br>
	 * 作者: 
	 * 时间: Oct 30, 2013 11:58:22 AM
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		// 异常的第一种处理方式(抛出)
		ExceptionTest4 test4 = new ExceptionTest4();
		test4.method("hello");
		// 代码执行到这行就会产生异常并抛出,后面的代码就不会再去执行了。
		test4.method(null);
		System.out.println("test");

		// // 异常的第二种处理方式
		// try {
		// ExceptionTest4 test = new ExceptionTest4();
		// test.method(null);
		// } catch (MyException e) {
		// e.printStackTrace();
		// } finally {
		// System.out.println("异常处理完毕");
		// }
		// System.out.println("程序执行完毕");
	}
}


Try…catch…finally结构里面的catch块可以有多个。每一个catch块捕获着一种特定类型的异常。总之凡是被调用方法有可能抛出的所有异常类型(一个方法是可以抛出多个异常类型,也可以抛出多个异常之间共有的父类,比如Exception来代替多个异常类型来抛出),你这里在catch块里面全都要捕获到,定义一个catch块不行就定义两个,定义两个不行就定义三个(也可以定义一个多个异常之间共有的父类来代替多个异常也可以,比如Exception),一直到都能捕获到为止。相应的异常出现的时候就进入到相应类型的catch块里面,但顶多只能有一个catch块被执行。


对于异常捕获来说,可以通过多个catch来去捕获我们的这个异常,但是一定要注意,他们的这种顺序关系是按照子类跟父类这种关系来排列的。顺序是按照子类在前父类在后的顺序来的,子类在前,父类在后,表示范围小的在前面(是针对多个catch块之间的异常类存在继承关系来说的),如果父类型的放在前面那么后面的子类型就没法去执行了就没有意义了。如果catch块和catch块之间的异常类型没有关系不存在继承关系,那么谁在前谁在后都可以。总结如下:
我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块后面,这样才能保证后续的catch可能被执行,否则子类型的catch将永远无法到达,Java 编译器会报编译错误;如果多个catch 块的异常类型是独立的(MyException, MyException2),  那么谁前谁后都是可以的。

如果try 块中存在return 语句,那么首先也需要将finally 块中的代码执行完毕,然后方法再返回(当然finally块后面的代码不会执行了。这种问题很无聊,根本没有什么实际用处,面试的时候会遇到,记住就行。)。

如果try 块中存在System.exit(0)语句,那么就不会执行finally 块中的代码,因为
System.exit(0)会终止当前运行的Java虚拟机,程序会在虚拟机终止前结束执行(这种问题也很无聊,没用。记住就行。)。


下面示例是一个实际开发中经常用到的一种使用异常的情况(相当于先把当前的异常捕获了,然后转换成自定义的异常抛出,给出用户自定义的提示处理异常):
package com.shengsiyuan.exception;

public class ExceptionTest5 {
	public void method() throws MyException {
		try {
			System.out.println("进入到try块");
			int a = 1;
			int b = 0;
			int c = a / b;
		} catch (Exception e) {
			System.out.println("异常发生了");
			// 相当于把当前可能出现的异常类型转化了,转化成自己自定义的异常类型,然后给用户相应的自定义信息并处理该异常。
			throw new MyException("转到自定义异常给用户提示!");
		} finally {
			System.out.println("进入到finally块");
		}
	}

	public static void main(String[] args) {
		ExceptionTest5 test = new ExceptionTest5();
		try {
			test.method();
		} catch (MyException e) {
			e.printStackTrace();
		}
	}
}
  • 大小: 57.8 KB
分享到:
评论

相关推荐

    java异常机制总结

    关键字:throws 声明方法时候,如果不声明throws的话,那么一般的Exception都要在这个方法中终结,也就是说一定要有相应的catch处理,否则编译时会产生错误。如果方法声明了throws的话,可以交给上一级方法去...

    Java 常见异常(Runtime Exception )详细介绍并总结

    主要介绍了Java 常见异常(Runtime Exception )详细介绍并相关资料,大家在开发Java 应用软件的时候经常会遇到各种异常这里帮大家整理了一部分,并解释如何解决,需要的朋友可以参考下

    常见JAVA异常总结

    总结的常见的JAVA异常。没有涵盖全部异常,但是包括了最常见的饿18中异常

    java 异常总结

    java.lang.ArithmeticException 算术条件异常。譬如:整数除零等。 java.lang.ArrayIndexOutOfBoundsException 数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。 java.lang.ArrayStoreException...

    Java 基础核心总结 +经典算法大全.rar

    《Java 基础核心总结》 Java 概述 什么是 Java2 Java 的特点Java 开发环境 JDK JRE Java 开发环境配置 Java 基本语法 数据类型基础语法运算符 Java 执行控制流程条件语句 if 条件语句 if...else 条件语句if...else ...

    java异常机制研究

    对java异常的总结,详细描述了JAVA异常的分类,异常的抛出和捕捉的机制,以及在项目应用中应该如何对异常作单独处理

    java基础核心总结归纳---参考手册--心得手册-学习资料-总结经验

    与 Exception 有关的 Java 关键字 19 什么是 Error 20 内部类 20 集合 20 ArrayList 21 Vector 21 LinkedList 21 Stack 21 HashSet 22 TreeSet 22 LinkedHashSet 22 HashMap 23 集合实现类特征图 23 泛形 23 反射 24...

    Java异常(Exception)

    在Java等面向对象的编程语言中,异常本身就是一个类,产生异常就是创建异常对象并抛出一个异常类,Java处理异常的方式是中断处理。 可能这时候你就会问了,你在这巴拉巴拉半天说啥呢? 那我们就来看一个例子,平常...

    java 面试题 总结

    java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 6、说出Servlet的生命周期,并说出Servlet和CGI的区别。 Servlet被服务器实例化后,容器运行其init方法,...

    exception.7z

    简单总结java异常,适合java初学者

    JAVA基础课程讲义

    第一个JAVA程序的总结和提升 20 常用Java开发工具 20 常用dos命令 21 本章笔试作业 21 本章上机操作 21 第二章(1) 编程的基本概念 22 注释 22 标识符 22 关键字/保留字 23 变量(variable) 24 常量(Constant) 25 命名...

    总结了java容易出错的信息 以及错误信息类型

    总结了java容易出错的信息 以及错误信息类型

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    11.2.5 总结:类的修饰符 297 11.3 方法的修饰符 297 11.3.1 方法的访问控制符 298 11.3.2 public:没有限制的修饰符 299 11.3.3 protected:仅对子类和同包的类可见 300 11.3.4 默认控制符:仅在本包中可见 ...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    11.2.5 总结:类的修饰符 297 11.3 方法的修饰符 297 11.3.1 方法的访问控制符 298 11.3.2 public:没有限制的修饰符 299 11.3.3 protected:仅对子类和同包的类可见 300 11.3.4 默认控制符:仅在本包中可见 ...

    java面试宝典.docx

    总结java中长长面试的要点,迅速的掌握面经,拿到offer 1. Thread.sleep() 和 Object.wait() Thread.sleep() 和 Object.wait() 都可以抛出 InterruptedException。这个异常是不能忽略的,因为它是一个检查异常...

    Python异常处理总结

    Python中的raise 关键字用于引发一个异常,基本上和C#和Java中的throw关键字相同,如下所示: # -- coding: utf-8 -- def ThorwErr(): raise Exception(抛出一个异常) # Exception: 抛出一个异

    java EE学习总结 第六周(包含思维导图)

    Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中。 -Error:JVM 、硬件、执行逻辑错误,不能手动处理 Exception:程序在运行和配置中产生的问题,可处理 RuntimeException:运行时异常,可处理,可不...

    整理后java开发全套达内学习笔记(含练习)

    Exception [java] 例外; 异常 [ik'sepʃәn] entry n.登录项, 输入项, 条目['entri] enum (关键字) execute vt.执行 ['eksikju:t] exhibit v.显示, 陈列 [ig'zibit] exist 存在, 发生 [ig'zist] '(SQL关键字 ...

    Java面试宝典2010版

    45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗? 29 46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法...

    Java EE 编码规范.docx

    5、异常( Exception )的命名 4 6、方法( Method )的命名 4 7、参数( Param )的命名 4 8、常量字段 ( Constants )的命名 4 三、注释规范 5 1、一般概念 5 2、注释哪些部分 5 3、注释格式 5 四、代码格式规范 ...

Global site tag (gtag.js) - Google Analytics