Java异常之throws和throw 以及异常使用注意的原则

一.使用throws抛出异常

如果在当前方法不知道该如何处理该异常时,则可以使用throws对异常进行抛出给调用者处理或者交给JVM。JVM对异常的处理方式是:打印异常的跟踪栈信息并终止程序运行。
throws在使用时应处于方法签名之后使用,可以抛出多种异常并用英文字符逗号’,’隔开
e.g.1
public void throwsTest() throws ExceptionClass1, ExceptionClass2 {...}
如果抛出给调用者的异常是Checked异常,这种异常是我们需要处理以来提高程序健壮性的,一般抛出则要调用者做相应处理,要么调用者对该异常进行try…catch处理,要么再次throws交给上一层。这其中需要注意一点:子类方法声明抛出的异常类型应是父类方法声明抛出的异常类型的子类或相同,子类方法声明跑出的异常不允许比父类方法声明抛出的异常多。
e.g.2

public class ThrowsTest2{
    //因为test();会抛出IOException,main方法是调用者
    //则需要使用try...catch进行捕获或者抛给JVM
    //抛出时要遵循父类声明抛出“大于”子类声明抛出的原则
    public static void main(String[] args) throws Exception {
        test();
    }
    public static void test() throws IOException() {
        //因为FileInputStream构造器会抛出IOException
        //所以需要使用try...catch块进行处理或使用throws抛给调用者
        FileInputStream fis = new FileInputStream("a.txt");
    }
}
二.使用throw抛出异常

如果需要程序在程序中自行抛出异常,应该使用throw语句抛出,抛出的不是一个类而是一个对象且只能抛出一个对象。它可以单独使用,也可以结合catch块捕获使用。如果抛出的异常对象时Checked异常则处于try块里被catch捕获或者放在一个带throws的方法里;如果抛出的是RuntimeException则既可以显示使用try…catch捕获也可以不理会它
e.g.3

public class ThrowTest {
    public static void main(String[] args) {
        try{
            throwChecked(3);
        }catch(Exception e) {
            System.out.println(e.getMessage());
        }
        throwRuntime(-3);
    }
    //该方法内抛出一个Exception异常对象,必须捕获或抛给调用者
    public static void throwChecked(int a) throws Exception {
        if(a < 0) {
            throw new Exception("a的值应大于0,不符合要求")
        }
    }
    //该方法内抛出一个RuntimeException对象,可以不理会直接交给JVM处理
    public static void throwRuntime(int a) {
        if(a < 0) {
            throw new RuntimeException("a的值应大于0,不符合要求")
        }
    }
}

Java7增强的throw语句:
在Java7之前,父类和子类在声明抛出异常时应符合父类包含的异常“大于等于”子类包含的异常的规则;从Java7开始,Java编译器会检查throw语句抛出的异常的实际类型,如下代码中编译器知道throw e只能抛出FileNotFoundException 所以在方法签名上可以直接写该异常:
e.g.4

public class ThrowTest2 {
    public static void main(String[] args) throws FileNotFoundException {
        try {
            new FileOutputStream("a.txt");
        }catch(Exception e) {
            e.printStackTrace();
            throw e;
        }
    }
}
三.自定义异常类

在抛出异常时,异常类名往往包含有用的信息,所以在选择抛出异常时需要选择适合的类,从而可以明确的描述该异常情况。这时候就需要我们自己定义异常,自定义异常一定是Throwable的子类,若是检查异常就要继承自Exception,若是运行时异常就要继承自RuntimeException
e.g.5

public class AuctionException extends Exception {
    //无参构造
    public AuctionException() {}
    //含参构造
    //通过调用父类的构造器将字符串msg传给异常对象的massage属性,
    //massage属性就是对异常的描述
    public AuctionException(String msg) {
        super(msg);
    }
}

关于自定义异常深入学习可以参考以下链接:
http://www.cnblogs.com/AlanLee/p/6104492.html

四.catch和throw同时使用

在实际应用中,在异常出现的当前方法中,程序只能对异常做部分处理,还有些处理需要在该方法的调用者才能够完成,使用需要再次抛出异常。这时,就需要将catch和throw结合使用。
e.g.6

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("竞拍价必须为数值,不能包含其它数值");
        }
        if(initPrice > d) {
            throw new AuctionException("竞拍价应比起拍价高");
        }
        initPrice = d;
    }
    public static void main(String[] args) {
        AuctionTest at = new AuctionTest();
        try{
            at.bid("..");
        }catch(AuctionException ae) {
            System.out.println(ae.getMessage());
        }
    }
}

以上代码的运行结果为:

竞拍价必须为数值,不能包含其它数值
java.lang.NumberFormatException: multiple points
    at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
    at sun.misc.FloatingDecimal.parseDouble(Unknown Source)
    at java.lang.Double.parseDouble(Unknown Source)
    at ExceptionTest.AuctionTest.bid(AuctionTest.java:15)
    at ExceptionTest.AuctionTest.main(AuctionTest.java:28)
五.异常链

把捕获一个异常然后接着抛出另一个异常,并把原始异常信息保存下来是一种典型的链式处理,也被称作异常链。

六.Java的异常跟踪栈

如e.g.6的运行结果
除去第一行打印的自定义的提示信息之外的第一行是异常的类型和详细消息,之后的提示信息中含有确切代码行数的信息记录了所有的异常发生点,各行显示被调用方法中执行的停止位置。跟踪栈总是最内部的被调用方法逐渐上传知道外部业务操作的起点,通常就是main方法或者Thread的run方法。

七.异常处理规则
  1. 不要过度使用异常:对于完全已知的错误应编写处理这种错误代码从而提高代码的健壮性,只有外部的、不能确定的和不可预知的运行时错误使是用异常,并且异常机制的效率低于正常的流程控制。
  2. 不要使用过于庞大的try块:过于庞大的try块业务也相对更复杂,会导致try块中异常的可能性大大增加,在分析发生异常的原因时难度增加。
  3. 避免使用Catch All语句:Catch All是catch(Throwable t),也会在发生异常是分析原因的复杂度增加。
  4. 不要忽略已捕获到的异常:对于捕获到的异常应该对其进行处理从而提高代码健壮性,而不是什么都不做或者只是打印跟踪栈信息。
  • 16
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: throws和throw都是Java用于处理异常的关键字。 throws用于在方法声明指定可能抛出的异常类型,表示该方法可能会抛出指定类型的异常,但并不处理该异常,而是将异常抛给调用该方法的上层方法处理。 throw则是用于在方法手动抛出异常,表示程序出现了某种异常情况,需要将异常抛出给上层方法进行处理。 总的来说,throws和throw都是用于异常处理的关键字,但它们的作用不同,throws用于声明可能抛出的异常类型,而throw则是手动抛出异常。 ### 回答2: Java异常处理是一种重要的编程技术,可以帮助开发人员更好地处理程序运行时出现的异常情况。在Java异常处理分为两种,一种是抛出(throw异常,另一种是捕获(try...catch)异常。其throwthrows是Java抛出异常的两种方式。 throw是指通过程序明确的语法,将异常抛出到调用方,并在调用方进行相应的异常处理。其使用方法如下: public void someMethod() throws Exception { // some code if (someCondition) { throw new Exception("Some exception message."); } // more code } 在这个例子,当条件someCondition满足时,会抛出一个新的Exception对象。因为这个方法使用throws关键字,因此在调用这个方法的地方,需要使用try...catch块或者将异常继续抛出。这可以帮助程序更好地处理异常情况。 而throws则是指在方法声明使用关键字throws来声明可能抛出的异常,让调用者知道可能会出现的异常情况。例如: public void someOtherMethod(int arg) throws Exception { // some code if (arg < 0) { throw new Exception("Argument must be positive."); } // more code } 在这个例子,someOtherMethod方法声明了可能会抛出Exception异常。因此,在调用这个方法的地方,如果不想使用try...catch块捕获异常,也可以使用throws将异常继续向外抛出。 总之,Java异常处理是一种重要的编程技术。在处理异常时,throwthrows都是非常有用的工具。通过使用它们,程序员可以更好地处理出现的异常情况,让程序更加健壮和可靠。 ### 回答3: 在Java异常是指程序运行时遇到的各种错误和异常情况,例如输入错误、网络异常、空指针引用等。为了避免程序崩溃,我们需要进行异常处理。 Java有两种异常处理方式:throws和throwthrows表示在方法声明时声明可能抛出的异常,让调用者来处理异常。例如: ``` public void readFromFile(String fileName) throws FileNotFoundException { FileInputStream fis = new FileInputStream(fileName); // 可能会抛出FileNotFoundException // ... } ``` 上面的方法声明了可能会抛出FileNotFoundException异常,这样在调用该方法时,就需要用try-catch语句捕获异常或者继续使用throws将异常抛给上层调用者。 throw表示在程序主动抛出一个异常。例如: ``` public int divide(int a, int b) throws Exception { if (b == 0) { throw new Exception("除数不能为0"); // 抛出异常 } return a / b; } ``` 上面的方法,如果除数为0,就会主动抛出一个Exception异常,并给出异常信息。这样的话,程序就会立即停止运行,而不会导致更大的问题。 总的来说,在实际开发,我们需要经常进行异常处理,尤其是在涉及到读写文件、网络通信、输入输出等场景下。throws和throw都是非常重要的异常处理方式,要熟练掌握使用。同时,建议在方法尽量避免使用throw,而利用返回值和异常信息来表示异常情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值