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");
}
}
评论
public class MyException1 extends Exception{
int num;
MyException1(int a)
{
num=a;
}
public String toString()
{
return num+"<10!值必须大于10";
}}
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)
{
System.out.println(""+e); }
catch(MyException2 e)
{
System.out.println(""+e);
}
}
}发表评论
我的相册
共 34 张
链接
最新评论
-
C3P0连接池的相关配置
c3p0使用实例 public class DBConn   ...
-- by beyondsanli -
优秀员工感想
写的很有内涵我很喜欢 挺有特色的
-- by blucedong -
编码之上传下载
import java.io.UnsupportedEncodingExcept ...
-- by beyondsanli -
由功夫熊猫想到的
评论转载自:http://bbs.gxsd.com.cn/viewthread. ...
-- by beyondsanli -
由功夫熊猫想到的
评论转载自:http://bbs.gxsd.com.cn/viewthread. ...
-- by beyondsanli







评论排行榜