Java错误处理

编写程序的过程中,我们除了实现功能外,也要保证其健壮性。其中之一就是包括对异常的处理。Java将非正常的情况分为Exception and error。其中error错误无法修复也不可捕获。异常机制已经成为判断一门编程语言是否成熟的标准。那么我们在写程序的过程中也需要写好对异常的处理机制。比如写入日志记录便于问题的排查,比如提示错误码告诉用户错误原因。虽然说异常处理的编写会有些乏味。

Java的异常机制主要依赖于try、catch、finally、throw、throws这五个关键字。Java将异常分为Checked和Runtime异常。Checked异常是编译阶段必须被处理的异常,否则程序发生错误无法通过编译。它体现了Java的设计哲学---没有完善错误处理的代码根本不会被执行。但是大部分的方法总是不能明确地知道如何处理异常,因此一定程度上checked异常降低了程序的生产率和代码的执行效率。

语法结构:

try
{
  //业务实现代码
  ....
}

catch(Exception e)
{
   //错误处理代码
}
finally
{
   //资源回收
}

栗子:

public class DivTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try
        {
            int a =Integer.parseInt(args[0]);
            int b =Integer.parseInt(args[1]);
            int c =a/b;
            System.out.println(c);

        }
        catch(IndexOutOfBoundsException ie)
        {
            System.out.println("数组越界");
        }
        catch(NumberFormatException ne)
        {
            System.out.println("数据格式异常");
        }
        catch(ArithmeticException ae)
        {
            System.out.println("算术异常");
        }
        catch(Exception e)
        {
            System.out.println("未知异常");
        }

    }

}

注:所有父类异常catch块都应该放在子类异常catch块的后面。

Java7提供的多异常捕获的异常变量有隐式final修饰,用|分开。

访问异常信息:

所有异常对象都包含了以下方法

getMessage()

printStackTrace()

printStackTrace(PrintStream s)

getStackTrace()

栗子:

public class AccessExceptionMsg {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try
        {
            FileInputStream fis = new FileInputStream("a.txt");
        }
        catch (IOException ioe)
        {
            System.out.println(ioe.getMessage());
            ioe.printStackTrace();
        }

    }

}

使用finally回收资源

public class FinallyTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        FileInputStream fis =null;
        try
        {
            fis = new FileInputStream("a.txt");
        }
        catch (IOException ioe)
        {
            System.out.println(ioe.getMessage());
            //return;//强制方法返回,但是一定会执行finally代码
            System.exit(1);//finally不会被执行
        }
        finally
        {
            if(fis!=null)
            {
                try
                {
                    fis.close();
                }
                catch(IOException ioe)
                {
                    ioe.printStackTrace();
                }
            }
            System.out.println("exe finally");
            //尽量避免在finally里写return和throw等语句,try,catch将不会被执行
        }

    }

}

注:Java7增强了try语句的功能---在try后面紧跟一对括号,括号里面可以声明、初始化一个或多个资源(数据库连接,网络连接等),try语句在该语句结束时自动关闭这些资源。

前提是这些资源类实现了AutoCloseable或Closeable接口。Java 7几乎把所有的“资源类”都进行改写,实现了AutoCloseable或Closeable接口.

throw和throws的区别

throws抛出异常的思路是:当前方法也不知道如何处理这种异常类型,交给上一级调用者处理。throws 声明抛出只能在方法签名中使用,抛出多个异常类用,分开。一旦用throws,程序无需用try..catch来捕获异常。例:main方法不知道如何处理异常,交给JVM处理。JVM处理异常的方法是:打印异常的跟踪栈信息,并终止程序运行。

throw是当程序出现错误时,系统自动跑出异常。抛出的是异常实例而不是异常类,而且每次只能抛出一个异常实例。如果是checked异常,throw语句要么在try块里,显示捕获该异常,要么放在一个throws声明抛出的方法中,交给该方法的调用者处理。

自定义异常类

继承Exception 或Runtime异常,必须提供两个构造器,一个无参数,一个带字符串,字符串用来描述异常对象的信息。

catch和throw结合来用

可以用几个方法协作处理异常,例如在方法内捕获处理和调用者处理。

public class AuctionTest {
    private double initPrice=30.0;
    public void bid(String bidPrice) throws AuctionException
    {
        double d =0.0;
        try
        {
            d=Double.parseDouble(bidPrice);
        }
        catch(Exception e)
        {
            e.printStackTrace();
            throw new AuctionException("must be a number!");
        }
        if(initPrice>d)
        {
            throw new AuctionException("lower than auction price!");
        }
        initPrice=d;
    }
    public static void main(String[] args)
    {
        AuctionTest at = new AuctionTest();
        try
        {
            at.bid("3");

        }
        catch(AuctionException ae)
        {
            System.err.println(ae.getMessage());
        }
    }

}

异常链

异常转译:捕获原始异常,抛出一个新的业务异常,新的业务异常中包含了对用户的提示信息。

23种设计模式之一:责任链模式

栗子:

public calSal() throws SalException
{
try
{
  // 实现工资结算的业务逻辑
  ...
}
catch(SQLException sqle)
{
//把原始异常记录下来,留给管理员
...

throw new SalException("访问数据库出现异常");
}
catch(Exception e)
{
//把原始异常记录下来,留给管理员
...

throw new SalException("系统出现未知异常");
}

public class SalException extends Exception
{
publlic SalException() {};
publlic SalException(String msg) {super(msg);};
publlic SalException(Throwable t) {super(t)};
}

Java异常跟踪栈

开发者可以通过printStackTrace()找到异常的源头。

public class ThreadExceptionTest implements Runnable{
    public void run()
    {
        firstMethod();
    }
    public void firstMethod()
    {
        secondMethod();
    }
    public void secondMethod()
    {
        int a =5;
        int b=0;
        int c=a/b;
    }
    public static void main(String[] args)
    {
        new Thread(new ThreadExceptionTest()).start();
    }

}

结果:
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
    at exceptionHandling.ThreadExceptionTest.secondMethod(ThreadExceptionTest.java:25)
    at exceptionHandling.ThreadExceptionTest.firstMethod(ThreadExceptionTest.java:19)
    at exceptionHandling.ThreadExceptionTest.run(ThreadExceptionTest.java:15)
    at java.lang.Thread.run(Thread.java:745)

异常处理规则

  • 使程序代码混乱最小化
  • 捕获并保留诊断信息
  • 通知合适的人员
  • 采用合适的方式结束异常活动

不要过度使用异常,只有对外部的,不能确定和预知的运行时错误才使用异常。

把大块的try块分割成多个可能出现异常的程序段落,并分别放于try块中,分别捕获处理.

catch到异常后,不要忽略,采取适当措施比如:

  • 处理异常,对异常进行合适的修复,或者绕过异常继续执行,或者提示用户重新操作....
  • 重新抛出异常,抛给上层调用者,直接用throws声明抛出该异常
时间: 2024-10-07 08:06:20

Java错误处理的相关文章

java 错误:Access restriction: The type Resource is not accessible due to restriction on required library

Eclipse 默认把这些受访问限制的API设成了ERROR.只要把Windows-Preferences-Java-Complicer- Errors/Warnings里面的Deprecated and restricted API中的Forbidden references(access rules)选为Warning就可以编译通过. java 错误:Access restriction: The type Resource is not accessible due to restrict

eclipse启动时弹出Failed to load the JNI shared library jvm.dll的Java错误

原因1:给定目录下jvm.dll不存在. 对策:(1)重新安装jre或者jdk并配置好环境变量.(2)copy一个jvm.dll放在该目录下. 原因2:eclipse的版本与jre或者jdk版本不一致 对策:要么两者都安装64位的,要么都安装32位的,不能一个是32位一个是64位. 原因2的概率更大一些,原因1不太可能发生 eclipse启动时弹出Failed to load the JNI shared library jvm.dll的Java错误,布布扣,bubuko.com eclipse

一些初级Java错误,不定期增加

1. Error: Dangling meta character '*' near index 0 对字符串使用split()方法截取 * ? + / | 等字符的时候会报以下异常 Dangling meta character '?' near index 0 ? +.*.|.\等符号在正则表达示中有相应的不同意义. 一般来讲只需要加[].或是\\即可 一些初级Java错误,不定期增加

Java - 错误: "java.lang.ArrayIndexOutOfBoundsException: length=1; index=1"

错误: "java.lang.ArrayIndexOutOfBoundsException: length=1; index=1" 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24464947 Java中, 错误: "java.lang.ArrayIndexOutOfBoundsException: length=1; index=1" ; 意思: 数组(Array)索引(Index)越界(Ou

常见的 java错误

生产过程中出现的问题正逐渐得到中层和最高管理层的重视.不管是身为开发人员还是架构师,下列的事项都应该得到你足够的重视以避免陷入未来的尴尬境地.你也可以把它作为排查问题的便签 测试中使用的数据集规模不合适.比如,生产过程中一个典型的场景就是只使用 1 到 3 个账户进行测试,而这个数量本应是 1000 到 2000 个的.在做性能测试时,使用的数据必须是真实并且未经裁剪的.不贴近真实环境的性能测试,可能会带来不可预料的性能.拓展和多线程问题.只有使用更大规模的数据集对应用程序进行测试,才能保证它正

Java错误和异常解析

Java错误和异常解析 错误和异常 在Java中, 根据错误性质将运行错误分为两类: 错误和异常. 在Java程序的执行过程中, 如果出现了异常事件, 就会生成一个异常对象. 生成的异常对象将传递Java运行时系统, 这一异常的产生和提交过程称为抛弃(throw)异常.当Java运行时系统得到一个异常对象时, 它将会沿着方法的调用栈逐层回溯, 寻找处理这一异常的代码. 找到能够处理这类异常的方法后, 运行时系统把当前异常对象交给这个方法进行处理, 这一过程称为捕获(catch)异常. Throw

java错误页面的练习

如果一个页面没有处理异常,那么页面将会显示,显然用户不希望看到这种页面,那么我们可以跳转到友好的页面.IE自作聪明可以换其他浏览器看效果. index.jsp <%@ page contentType="text/html;charset=GBK" language="java" errorPage="errorPage.jsp" %> <%@ page import="java.sql.*" %> &

【JAVA错误笔记】 - c3p0问题java.lang.NoClassDefFoundError:com.mchange.v2.ser.Indirector

错误描述:java.lang.NoClassDefFoundError:com.mchange.v2.ser.Indirector 原因分析: 这是c3p0的一个错误信息,我们在下载 c3p0时候,zip压缩包中,有三个jar,其中一个 c3p0-x.x.x.jar,还有一个  mchange.......jar的文件, 该错误原因就是缺少该jar;至于 该jar包的作用就是,一,解决上面的问题,二:本身作用,见,,,jar解压后的源码. 解决方案: mchange-commons-java-版

java 错误:找不到或无法加载主类

1.检查环境变量: JAVA_HOME D:\Program Files\jdk1.8.0_45(这里写jdk路径) CLASSPATH .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(第一个点表示当前路径) Path ;%JAVA_HOME%\bin(在最后加上,结尾没有分号) 2.写一个测试类,Test.java 1 public class Test { 2 public static void main(String[] args) { 3 Sys