JAVA异常
JAVA异常
介绍
异常是在程序中出现的不符合预期的各种情况。它是程序设计的一部分,异常并不是错误,它不一定是坏的情况。JAVA有错误和异常两种不同的类型,其中错误(ERROR)指的是程序无法处理的错误,异常(Exception)指的是程序本身可以处理的异常。
-
ERROR:程序无法处理,这表明程序中出现严重的问题。大多与JVM有关,例如JVM内存不够的时候,将出现OutOfMemoryError。
-
EXCEPTION:程序可以处理,分为运行时异常(Runtime Exception)和非运行时异常。
- 运行时异常也是Unchecked Exception, 这些不会在编译期进行检查,会在程序运行期间出现问题的时候出现。这些异常一般都是程序执行造成的错误,需要尽量避免这种错误。
- 非运行时异常是checked Exception,也就是程序会在编译期进行检查,例如IOException。
异常的处理方式
异常的处理机制有捕获异常和抛出异常。
捕获异常的一般结构:
try
{
// 可能发生异常的代码
// 如果发生了异常,那么异常之后的代码都不会被执行
}
catch (Exception e)
{
// 异常处理代码
}
finally
{
// 不管有没有发生异常,finally语句块都会被执行
}
用除法举例说明:
public class ExceptionTest
{
public static void main(String[] args)
{
int c = 0;
try
{
int a = 3;
int b = 0;
// 这块代码出现了异常
c = a / b;
// 那么异常之后的代码都不会被执行
System.out.println("Hello World");
}
catch (ArithmeticException e)
{
e.printStackTrace();
}
finally
{
//不管有没有发生异常,finally语句块都会被执行
System.out.println("Welcome");
}
System.out.println(c);
// 当b为0时,有异常,输出为c的初始值0
}
}
当然一个try后面可以跟多个catch,但是不管多少个,最多只会有一个catch块被执行。
非运行时异常的处理方式
处理方式有两种:
1.使用try..catch..finally进行捕获;
2.在产生异常的方法声明后面写上throws 某一个Exception类型,如throws Exception,将异常抛出到外面一层去。
处理方式1:将异常捕获
将异常捕获
public class ExceptionTest2
{
public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
{
System.out.println("Hello World");
// 抛出异常
throw new Exception();
}
public static void main(String[] args)
{
ExceptionTest2 test = new ExceptionTest2();
try
{
test.method();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
System.out.println("Welcome");
}
}
}
处理方式2:将异常继续向外抛出
将异常抛出
public class ExceptionTest2
{
public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
{
System.out.println("Hello World");
// 抛出异常
throw new Exception();
}
public static void main(String[] args) throws Exception // main方法选择将异常继续抛出
{
ExceptionTest2 test = new ExceptionTest2();
test.method(); // main方法需要对异常进行处理
// 执行结果:
// Hello World
// Exception in thread "main" java.lang.Exception
// at com.learnjava.exception.ExceptionTest2.method(ExceptionTest2.java:10)
// at com.learnjava.exception.ExceptionTest2.main(ExceptionTest2.java:17)
}
}
运行时异常的处理方式
对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐不对运行时异常进行处理。
自定义异常
所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须直接或者间接地继承自Exception类。
通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。
自定义异常可以用于处理用户登录错误,用户输入错误提示等。
自定义异常的例子:
自定义一个异常类型:
public class MyException extends Exception
{
public MyException()
{
super();
}
public MyException(String message)
{
super(message);
}
}
处理方式
处理方式也分为throws 和 try...catch
一种异常处理方式
public class ExceptionTest4
{
public void method(String str) throws MyException
{
if(null == str)
{
throw new MyException("传入的字符串参数不能为null!");
}
else
{
System.out.println(str);
}
}
public static void main(String[] args) throws MyException //异常处理方式1,不断向外抛出
{
ExceptionTest4 test = new ExceptionTest4();
test.method(null);
}
}
Throws抛出异常的规则:
1) 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。
2)必须声明方法可抛出的任何可查异常(checked exception)。即如果一个方法可能出现受可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误
3)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。
4)调用方法必须遵循任何可查异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。
异常处理方式二
public class ExceptionTest4
{
public void method(String str) throws MyException
{
if (null == str)
{
throw new MyException("传入的字符串参数不能为null!");
}
else
{
System.out.println(str);
}
}
public static void main(String[] args)
{
//异常处理方式2,采用try...catch语句
try
{
ExceptionTest4 test = new ExceptionTest4();
test.method(null);
}
catch (MyException e)
{
e.printStackTrace();
}
finally
{
System.out.println("程序处理完毕");
}
}
}
前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个catch块。
try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch 块:用于处理try捕获到的异常。
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。
在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。
自定义异常
下面这个例子,定义了两种自定义的异常类型:
多种异常
public class MyException extends Exception
{
public MyException()
{
super();
}
public MyException(String message)
{
super(message);
}
}
public class MyException2 extends Exception
{
public MyException2()
{
super();
}
public MyException2(String message)
{
super(message);
}
}
public class ExceptionTest4
{
public void method(String str) throws MyException, MyException2
{
if (null == str)
{
throw new MyException("传入的字符串参数不能为null!");
}
else if ("hello".equals(str))
{
throw new MyException2("传入的字符串不能为hello");
}
else
{
System.out.println(str);
}
}
public static void main(String[] args)
{
// 异常处理方式2,采用try...catch语句
try
{
ExceptionTest4 test = new ExceptionTest4();
test.method(null);
}
catch (MyException e)
{
System.out.println("进入到MyException catch块");
e.printStackTrace();
}
catch (MyException2 e)
{
System.out.println("进入到MyException2 catch块");
e.printStackTrace();
}
finally
{
System.out.println("程序处理完毕");
}
}
}
我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译器会报错。
如果异常类型是独立的,那么它们的前后顺序没有要求。
JAVA常见异常
在Java中提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,有的是由Java虚拟机自动进行捕获处理。Java中常见的异常类:
-
runtimeException子类:
- java.lang.ArrayIndexOutOfBoundsException
数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。 - java.lang.ArithmeticException
算术条件异常。譬如:整数除零等。 - java.lang.NullPointerException
空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等 - java.lang.ClassNotFoundException
找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。 - java.lang.NegativeArraySizeException 数组长度为负异常
- java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常
- java.lang.SecurityException 安全性异常
- java.lang.IllegalArgumentException 非法参数异常
- java.lang.ArrayIndexOutOfBoundsException
-
IOException
- IOException:操作输入流和输出流时可能出现的异常。
- EOFException 文件已结束异常
- FileNotFoundException 文件未找到异常
-
其他
- ClassCastException 类型转换异常类
- ArrayStoreException 数组中包含不兼容的值抛出的异常
- SQLException 操作数据库异常类
- NoSuchFieldException 字段未找到异常
- NoSuchMethodException 方法未找到抛出的异常
- NumberFormatException 字符串转换为数字抛出的异常
- StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
- IllegalAccessException 不允许访问某类异常
- InstantiationException 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常
转载自:
1. http://www.cnblogs.com/mengdd/archive/2013/02/03/2890923.html
2. http://blog.csdn.net/hguisu/article/details/6155636
posted on 2016-06-14 18:07 walkwalkwalk 阅读(265) 评论(0) 编辑 收藏 举报