欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA 异常 throwable exception error throws throw

程序员文章站 2022-07-15 12:54:24
...
[b][color=green]1.如何理解Exception,Error和Throwable[/color][/b]
Throwable是Exception和Error的父类.
Error表示错误,一般是系统级的错误!
Exception一般是程序运行期间的错误!

通常在使用 try{}catch(Exception e){} 这种结构的时候,只能找到一半的错误,也就是说只能捕获Exception范围内的异常 并处理使得程序能够正常运行.而Error范围内的错误就无法捕获并处理.

通过 try{}catch(Throwable a){} 的方式能够处理,但是一般情况下不这样做。
原因在于查看Error下面的子类,VirtualMachineError,ThreadDeath,LinkageError,从名字上看出来这些错误都是非常非常严重的,到底是否需要去捕获或者处理呢?

Error的产生一般是JVM或者是操作系统的问题,JAVA 文档中对Error的说明是:"Error是Throwable的子类,它的出现说明出现了严重的问题。一般应用程序除非有理由,否则不应该捕捉Error,通常这是非常反常的情况".

Exception的产生主要是在程序运行期间发生的一些不正常事件中止了程序的运行,可以通过JAVA异常处理机制捕获异常并处理,使得程序正常运行下去。这些异常(不正常事件)有别于Error错误,它们通常是可修复的,程序员可以处理的。

[b][color=green]2.运行时异常和受检查异常[/color][/b]
1)运行时异常,属于RuntimeException类及子类范围的类(以及衍生类)都属于运行时异常。
2)受检查异常,在Exception范围内,除了运行时异常的类都是受检查异常类,为checked exception
3)它们之间的区别在于: 例如在代码中写了 throw new Exception(); 和 throw new RuntimeException();

两者都会在运行期间抛出异常!
但是在编译阶段前者的属于抛出一个受检查异常,要求对它进行显式的try..catch 捕获处理或者向上一层方法抛出,否则在编译期间就显示错误!
后者抛出是运行时异常,在编译阶段不予检查,语法上不会显示任何错误!
所以简单的通过throw手动抛出受检查异常 和抛出运行时异常,前者要求显式处理,后者不要求作出处理。

[b][color=green]3.throw 和throws的区别[/color][/b]

1)throw 是手动抛出异常,throw new **Exception(); 抛出的是某一个异常类型的实例.
2)throws 是方法抛出异常,写在方法声明处 public void show()throws **Exception,**Exception{} 紧跟throws后的是异常类型,而非异常实例,且可以声明抛出多个异常,同时这些异常类型大多都为 受检查异常类型。
3)throw 是程序员手动抛出异常,一般可用在某种流程控制,需要显示操作失误情况下可对外抛出异常,进入catch代码块,明示操作有误等。
throws 方法抛出异常,通常是告知调用此方法者,本方法有可能抛出一个异常,在调用时应当要进行异常监控。且因为throws方法抛出异常为受检查异常类型,这样就从语法上要求更需要对受检查异常类型作出捕获,或者再次向上抛出。

例如: JDBC中 public static Class forName(String className)throws ClassNotFoundException 加载驱动类时,调用此方法.

因为方法声明出 throws ClassNotFoundException 就告诉了方法调用者 本方法有可能会发生 ClassNotFoundException 异常,因为需要在调用此方法时格外注意。且此异常类型是受检查类型,那么在编译阶段就更要求用户调用时必须加上 try..catch(){}语句块,或者再次往上方法声明抛出 ClassNotFoundException 交由上层方法声明抛出 。

throws 方法抛出异常的两种处理方式
(1)try{
Class.forName("com.microsoft.....");
}catch(ClassNotFoundExceptioin e){
...
}

(2)
public Connection getConnection()throws ClassNotFoundException{
Class.forName("com.microsoft....");
}


如果把ClassNotFoundException 改为RuntimeException 就无需处理,那也就失去了方法抛出异常的意义了。

[color=green][b]4.常见的运行时异常[/b][/color]
ArithmaticExceptionDemo.java
/**
* 当除数为 0 时的异常 是运行时异常 编译时并不报错 只会在运行时发生
* @author Simon Lv
*
*/
public class ArithmaticExceptionDemo {
//计算两个数相除的结果
public int divide(int a,int b){
return a/b;
}

//抛出异常
//Exception in thread "main" java.lang.ArithmeticException: / by zero
public static void main(String args[]){
ArithmaticExceptionDemo excp = new ArithmaticExceptionDemo();
excp.divide(10,0);
}
}


ArrayStoreExceptionDemo.java
/**
* 演示 试图将一个错误的对象 存储到一个数组时发生的异常 ArrayStoreException
* @author Simon Lv
*
*/
public class ArrayStoreExceptionDemo {

//程序的入口
public static void main(String arsg[]){
//Object类型 字符串数组
Object x[] = new String[3];

//为了不让程序在编译时就检查报错 就故意写成上述类型
//如果写成 下面类型就会直接报错
//String x [] = new String[3];

try{
//错误的类型 java.lang.ArrayStoreException: java.lang.Integer
x[0] = new Integer(0);
}catch(ArrayStoreException ae){
System.err.println(ae.toString()+"ok");
ae.printStackTrace();
}

System.out.println("程序正常运行!");
}

}


ClassCastExceptionDemo.java
/**
* 类 类型装换异常 当试图将对象强制转换为不是实例的子类时,抛出该异常 ClassCastException
* @author Simon Lv
*
*/
public class ClassCastExceptionDemo {

public static void main(String args[]){

Object x = new Integer(12);

try{
System.out.println((String)x);
}catch(ClassCastException ce){
System.err.println(ce.toString());
}
}

}


EmptyStackExceptionDemo.java
import java.util.EmptyStackException;
import java.util.Stack;

/**
* 演示堆栈为空的异常 EmptyStackException
* @author Simon Lv
*
*/
public class EmptyStackExceptionDemo {

public static void main(String args[]){

Stack<String> s = new Stack<String>(); //栈
s.push("a"); //先压入 a 压栈 push()方法
s.push("b"); // b
s.push("c"); // 最后压入 c

try{
while(s.size()>0){
System.out.println( s.pop()); //依次循环将栈中的元素弹出 pop()方法
}
s.pop(); // 此动作将造成异常,因为栈中所有元素在上面的 循环中就已经弹出,为空栈
}catch(EmptyStackException ee){
System.err.println(ee.toString());
ee.printStackTrace();
}
}
}


IndexOutOfBoundsExceptionDemo.java
/**
* 演示 IndexOutOfBoundsException 异常
* 指某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
* @author Simon Lv
*
*/
public class IndexOutOfBoundsExceptionDemo {

public static void main(String args[]){
int num [] = new int[10];
try{
//数组10个长度 12次循环就报错
for(int i=0;i<12;i++){
System.out.println(num[i]); //循环超出范围
}
}catch(IndexOutOfBoundsException ie){
System.err.println(ie.toString());
ie.printStackTrace();
System.out.println( ie.getCause());
System.err.println(ie.getMessage());

}

System.out.println("程序还 能继续执行");
}
}


NegativeArraySizeExceptionDemo.java

/**
* 演示 NegativeArraySizeException 异常
* 如果应用程序试图创建大小为负的数组,则抛出该异常。
* @author Simon Lv
*
*/
public class NegativeArraySizeExceptionDemo {

public static void main(String args[]){

try{
int num [] = new int [-9]; //创建大小为负的数组,则抛出该异常。
System.out.println(num[0]);
}catch(NegativeArraySizeException ne){
System.err.println(ne.toString()); //err红色打印
ne.printStackTrace();
}
}
}



NullPointerExceptionDemo.java
/**
* 当应用程序试图在需要对象的地方使用 null 时,抛出该异常。这种情况包括:
调用 null 对象的实例方法。
访问或修改 null 对象的字段。
将 null 作为一个数组,获得其长度
将 null 作为一个数组,访问或修改
将 null 作为 Throwable 值抛出
应用程序应该抛出该类的实例,指示其他对 null 对象的非法使用

* @author Simon Lv
*
*/
public class NullPointerExceptionDemo {

String nameString; //类字符串成员变量 默认为null

public static void main(String args[]){

try{
//返回字符串第一个字符 但将出现异常 相当于 null.charAt(0);
char c = new NullPointerExceptionDemo().nameString.charAt(0);

System.out.println(c);
}catch(NullPointerException ne){
System.err.println(ne.toString());
ne.printStackTrace();
}
}

}


NumberFormatExceptionDemo.java
/**
* 演示格式转换异常 NumberFormatException
* 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常
* @author Simon Lv
*
*/
public class NumberFormatExceptionDemo {

public static void main(String args[]){

String a = "3";
int b = (int)new Integer(a);
System.out.println(b);//这个是没有问题的

try{
String c = "aa";
//java.lang.NumberFormatException: For input string: "aa"
int d = (int)new Integer(c);

System.out.println(d);//这个是有问题的
}catch(NumberFormatException ne){
System.err.println(ne.toString());
ne.printStackTrace();
}
}
}