`

java异常中Runtime点滴学习

阅读更多

特别关注一下 RuntimeException

 

检查性异常 checked
 java.io.FileInputStream类的read()方法抛出IoException,方法无法履行它的职责
非检查型异常non-checked  运行时异常runtimeException
类的误用 String.chartAt StringIndexOutBoundsException
SUN公司并不打算强制客户程序员每次调用charAt(int index)时都检查index参数的合法性。

 


上面刚刚讨论了一下 Error 类型的异常处理情况, Java 程序员一般无须关注它(处理这种异常)。另外,其实在 Exception 类型的异常对象中,也存在一种比较特别的“异常”类型,那就是 RuntimeException ,虽然它是直接从 Exception 派生而来,但是 Java 编译器( javac )对 RuntimeException 却是特殊待遇,而且是照顾有加。不信,看看下面的两个示例吧!代码如下:
// 示例程序 1
// 它不能编译通过,我们可以理解

 

import java.io.*;

public class Trans {
        public static void main(String[] args) {
                test();
        }

        static void test() {
                // 注意这条语句
                throw new Exception(" 故意抛出一个 Exception");
        }
} 

 // 示例程序 2
// 可它却为什么能够编译通过呢?

import java.io.*;

public class Trans {
        public static void main(String[] args) {
                test();
        }

        static void test() {
                // 注意这条语句
                throw new RuntimeException(" 故意抛出一个 RuntimeException");
        }
} 

 对上面两个相当类似的程序, javac 编译时却遭遇了两种截然不同的处理,按理说,第 2 个示例程序也应该像第 1 个示例程序那样,编译时报错!但是 javac 编译它时,却例外地让它通过它,而且在运行时, java 虚拟机也捕获到了这个异常,并且会在 console 打印出详细的异常信息。运行结果如下:
java.lang.RuntimeException: 故意抛出一个 RuntimeException
at Trans.test(Trans.java:13)
at Trans.main(Trans.java:8)
Exception in thread "main"
为什么对于 RuntimeException 类型的异常(以及从它派生而出的异常类型), javac 和 java 虚拟机都特殊处理呢?要知道,这可是与“ Java 异常处理模型更严谨和更安全”的设计原则相抵触的呀!究竟是为何呢?这简直让人不法理解呀!
只不过, Java 语言中, RuntimeException 被统一纳入到了 Java 语言和 JDK 的规范之中。请看如下代码,来验证一下我们的理解!

import java.io.*; 
public class Trans 
{ 
public static void main(String[] args) 
{ 
test(); 
} 
static void test() 
{ 
int i = 4; 
int j = 0; 
// 运行时,这里将触发了一个 ArithmeticException 
// ArithmeticException 从 RuntimeException 派生而来 
System.out.println("i / j = " + i / j); 
} 
} 

 运行结果如下:
java.lang.ArithmeticException: / by zero
at Trans.test(Trans.java:16)
at Trans.main(Trans.java:8)
Exception in thread "main"
又如下面的例子,也会产生一个 RuntimeException ,代码如下:

import java.io.*; 
public class Trans 
{ 
public static void main(String[] args) 
{ 
test(); 
} 
static void test() 
{ 
String str = null; 
// 运行时,这里将触发了一个 NullPointerException 
// NullPointerException 从 RuntimeException 派生而来 
str.compareTo("abc"); 
} 
} 

 所以,针对 RuntimeException 类型的异常, javac 是无法通过编译时的静态语法检测来判断到底哪些函数(或哪些区域的代码)可能抛出这类异常(这完全取决于运行时状态,或者说运行态所决定的)理解为non_checked可以?,也正因为如此, Java 异常处理模型中的“ must be caught or declared to be thrown ”规则也不适用于 RuntimeException (所以才有前面所提到过的奇怪编译现象,这也属于特殊规则吧)。但是, Java 虚拟机却需要有效地捕获并处理此类异常。当然, RuntimeException 也可以被程序员显式地抛出,而且为了程序的可靠性,对一些可能出现“运行时异常( RuntimeException )”的代码区域,程序员最好能够及时地处理这些意外的异常,也即通过 catch(RuntimeExcetion) 或 catch(Exception) 来捕获它们。如下面的示例程序,代码如下:

import java.io.*; 
public class Trans 
{ 
public static void main(String[] args) 
{ 
try 
{ 
test(); 
} 
// 在上层的调用函数中,最好捕获所有的 Exception 异常! 
catch(Exception e) 
{ 
System.out.println("go here!"); 
e.printStackTrace(); 
} 
} 
// 这里最好显式地声明一下,表明该函数可能抛出 RuntimeException 
static void test() throws RuntimeException 
{ 
String str = null; 
// 运行时,这里将触发了一个 NullPointerException 
// NullPointerException 从 RuntimeException 派生而来 
str.compareTo("abc"); 
} 
} 

 

分享到:
评论
2 楼 qichunren 2008-05-27  
总结得不错.
1 楼 beyondsanli 2008-05-19  
自定义异常小例子,(注意下toString同System.out之间的关系)
public class MyException1 extends Exception{
	int num;
	MyException1(int a)
	{
		num=a;
		
	}
  [color=red] public String toString()
   {
	   return num+"<10!值必须大于10";
   }[/color]}


public class MyException2 extends Exception{
	int num;
	
	MyException2(int a)
	{
		num=a;
	}
	public String toString()
	{
		return num+">100值必须小于100";
	}
}



public class MyExceptionTest {

	/**
	 * @param args
	 */
	
	static void makeException(int a)throws MyException1,MyException2
	{
		if(a<10)
			throw new MyException1(a);
		 if(a>100)
	            throw new MyException2(a);
	        System.out.println("No Exception");

	}
	public static void main(String[] args) {
		// TODO 自动生成方法存根
            int a;
            try
            {
            	//makeException(6);
            	makeException(600);
            }
            catch (MyException1 e)
            {
               [color=red] System.out.println(""+e);[/color]            }
            catch(MyException2 e)
            {
                System.out.println(""+e);
            }

	}

}



相关推荐

Global site tag (gtag.js) - Google Analytics