Home  >  Article  >  Java  >  Java improvement (seventeen)-----Exception (two)

Java improvement (seventeen)-----Exception (two)

黄舟
黄舟Original
2017-02-10 11:45:301029browse

Continuing from the previous blog post: Java Improvement Chapter (16)-----Exception (1)

# 5. Custom exception

       Java does provide us with a lot of exceptions, but the exception system cannot foresee all the errors that we want to report, so Java allows us to customize exceptions. It represents specific problems that may be encountered in the program. In a word: we don't have to stick to the existing exception types in Java.

The use of Java custom exceptions requires the following four steps:

       1. Define a class that inherits Throwable or its subclass.

2. Add a constructor (of course, you can also use the default constructor without adding it).

         3. Throw this exception in a certain method class.

4. Catch the exception.

##

/** 自定义异常 继承Exception类 **/
public class MyException extends Exception{
    public MyException(){
        
    }
    
    public MyException(String message){
        super(message);
    }
}

public class Test {
    public void display(int i) throws MyException{
        if(i == 0){
            throw new MyException("该值不能为0.......");
        }
        else{
            System.out.println( i / 2);
        }
    }
    
    public static void main(String[] args) {
        Test test = new Test();
        try {
            test.display(0);
            System.out.println("---------------------");
        } catch (MyException e) {
            e.printStackTrace();
        }
    }
}

#Run result:

#                                                       

          There is a design pattern called the chain of responsibility pattern, which links multiple objects into a chain. The client The request is passed along this chain until it is received and processed. Similarly, the Java exception mechanism also provides such a chain: exception chain.

We know that every time we encounter an exception message, we need to try...catch, one is okay , what if multiple exceptions occur? Classification processing will definitely be more troublesome, so use one Exception to solve all exceptions. This is indeed possible, but this approach will inevitably make subsequent maintenance more difficult. The best way is to encapsulate these exception information and then capture our encapsulation class.

It is true that in applications, we sometimes not only need to encapsulate exceptions, but also need to pass them on. How to deliver? throws! binge, correct! ! But if you just use throws to throw exceptions, what should you do with your encapsulated class? ? We have two ways to handle exceptions. One is to throw it to the superior for processing, and the other is to try...catch does specific processing. But how does this relate to the above? We don't need to do any processing in the catch block of try...catch. We just use the throw keyword to actively throw the exception information we encapsulate. Then continue to throw the method exception through the keyword throws. Its upper layer can also perform such processing, and by analogy, an exception chain composed of exceptions will be generated.

##​​​​

By using exception chains, we can improve the understandability of the code. System maintainability and friendliness.

      同理,我们有时候在捕获一个异常后抛出另一个异常信息,并且希望将原始的异常信息也保持起来,这个时候也需要使用异常链。

      在异常链的使用中,throw抛出的是一个新的异常信息,这样势必会导致原有的异常信息丢失,如何保持?在Throwable及其子类中的构造器中都可以接受一个cause参数,该参数保存了原有的异常信息,通过getCause()就可以获取该原始异常信息。

      语法:

public void test() throws XxxException{
        try {
            //do something:可能抛出异常信息的代码块
        } catch (Exception e) {
            throw new XxxException(e);
        }
    }

      示例:

public class Test {
    public void f() throws MyException{
         try {
            FileReader reader = new FileReader("G:\\myfile\\struts.txt");  
             Scanner in = new Scanner(reader);  
             System.out.println(in.next());
        } catch (FileNotFoundException e) {
            //e 保存异常信息
            throw new MyException("文件没有找到--01",e);
        }  
    }
    
    public void g() throws MyException{
        try {
            f();
        } catch (MyException e) {
            //e 保存异常信息
            throw new MyException("文件没有找到--02",e);
        }
    }
    
    public static void main(String[] args) {
        Test t = new Test();
        try {
            t.g();
        } catch (MyException e) {
            e.printStackTrace();
        }
    }
}


      运行结果:

com.test9.MyException: 文件没有找到--02
    at com.test9.Test.g(Test.java:31)
    at com.test9.Test.main(Test.java:38)
Caused by: com.test9.MyException: 文件没有找到--01
    at com.test9.Test.f(Test.java:22)
    at com.test9.Test.g(Test.java:28)
    ... 1 more
Caused by: java.io.FileNotFoundException: G:\myfile\struts.txt (系统找不到指定的路径。)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:106)
    at java.io.FileInputStream.<init>(FileInputStream.java:66)
    at java.io.FileReader.<init>(FileReader.java:41)
    at com.test9.Test.f(Test.java:17)
    ... 2 more

      如果在程序中,去掉e,也就是:throw new MyException("文件没有找到--02");

      那么异常信息就保存不了,运行结果如下:

com.test9.MyException: 文件没有找到--02
    at com.test9.Test.g(Test.java:31)
    at com.test9.Test.main(Test.java:38)

      PS:其实对于异常链鄙人使用的也不是很多,理解的不是很清楚,望各位指正!!!!

       七、异常的使用误区

      首先我们先看如下示例:该实例能够反映java异常的不正确使用(其实这也是我刚刚学Java时写的代码)!!

OutputStreamWriter out = null;
        java.sql.Connection conn = null;
        try {            //   ---------1
            Statement stat = conn.createStatement();
            ResultSet rs = stat.executeQuery("select *from user");
            while (rs.next()){
                out.println("name:" + rs.getString("name") + "sex:"
                        + rs.getString("sex"));
            }
            conn.close();         //------2
            out.close();
        } 
        catch (Exception ex){    //------3
            ex.printStackTrace();    //------4
        }


      1、-----------1

      对于这个try…catch块,我想他的真正目的是捕获SQL的异常,但是这个try块是不是包含了太多的信息了。这是我们为了偷懒而养成的代码坏习惯。有些人喜欢将一大块的代码全部包含在一个try块里面,因为这样省事,反正有异常它就会抛出,而不愿意花时间来分析这个大代码块有那几块会产生异常,产生什么类型的异常,反正就是一篓子全部搞定。这就想我们出去旅游将所有的东西全部装进一个箱子里面,而不是分类来装,虽不知装进去容易,找出来难啊!!!所有对于一个异常块,我们应该仔细分清楚每块的抛出异常,因为一个大代码块有太多的地方会出现异常了。

      结论一:尽可能的减小try块!!!

      2、--------2

What did you find here? Exceptions change the running process! ! What’s good is that exceptions change the program’s running flow. If an exception occurs in the program, conn.close();out.close(); is impossible to execute, which will inevitably result in resources not being released. Therefore, if the program uses resources such as files, Sockets, and JDBC connections, even if an exception is encountered, we must ensure that the occupied resources can be released correctly. This is where finally comes in: no matter whether an exception occurs or not, finally always has a chance to run, so finally is perfect for releasing resources.

         Conclusion 2: Ensure that all resources are released correctly. Make full use of the finally keyword.

#                         ----------3

#           

For this code I think most people deal with it this way, (LZ too). People who use such code have the mentality that one catch can solve all exceptions. This is possible, but it is not recommended! Why! First of all, we need to understand that the catch block represents what kind of exception it expects to occur and what kind of processing needs to be done. Using Exception means that it has to handle all exception information, but what is the meaning of doing so? ​​​​

Here let’s take a look at the above program example again. Obviously it may need to throw Two exception information, SQLException and IOException. So it is obviously inappropriate for one catch to handle two completely different Exceptions. It would be much better if you use two catches, one to handle SQLException and one to handle IOException. So:

##Conclusion 3: The catch statement should be as specific as possible exception type, and should not specify an Exception class that covers too broad a range. Don't try to handle all possible exceptions with one Exception. #            

4, --- -------4

This is the problem There are so many, I can guarantee that almost everyone has used them this way. There are two problems involved here. One is that the exception is caught but not handled, and the other is that the exception information is not clear enough. ​​​​

4.1. Catching exceptions without processing them is what we call discarding exceptions. We all know that exceptions mean that an unexpected problem has occurred in the program. The program hopes that we can handle it to save it, but what about you? Just one sentence of ex.printStackTrace() is enough. How irresponsible it is to ignore the abnormal situation of the program. Although this may be helpful during debugging, what about after the debugging phase is over? Not everything can be done with just ex.printStackTrace()!

So how to improve? There are four options:

             

1. Handle exceptions. Handle the exceptions that occur, such as correcting errors and providing reminders. Again, ex.printStackTrace() does not count as "handling the exception".

      2、重新抛出异常。既然你认为你没有能力处理该异常,那么你就尽情向上抛吧!!!

      3、封装异常。这是LZ认为最好的处理方法,对异常信息进行分类,然后进行封装处理。

      4、不要捕获异常。

      4.2、异常信息不明确。我想对于这样的:java.io.FileNotFoundException: ………信息除了我们IT人没有几个人看得懂和想看吧!所以在出现异常后,我们最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。起码我公司是需要将异常信息所在的类、方法、何种异常都需要记录在日志文件中的。

所以:

      结论四:既然捕获了异常,就要对它进行适当的处理。不要捕获异常之后又把它丢弃,不予理睬。 不要做一个不负责的人。

      结论五:在异常处理模块中提供适量的错误原因信息,组织错误信息使其易于理解和阅读。

      对于异常还有以下几个注意地方:

      六、不要在finally块中处理返回值。

      七、不要在构造函数中抛出异常。



       八、try…catch、throw、throws

      在这里主要是区分throw和throws。

      throws是方法抛出异常。在方法声明中,如果添加了throws子句,表示该方法即将抛出异常,异常的处理交由它的调用者,至于调用者任何处理则不是它的责任范围内的了。所以如果一个方法会有异常发生时,但是又不想处理或者没有能力处理,就使用throws吧!

      而throw是语句抛出异常。它不可以单独使用,要么与try…catch配套使用,要么与throws配套使用。

//使用throws抛出异常
    public void f() throws MyException{
         try {
            FileReader reader = new FileReader("G:\\myfile\\struts.txt");  
             Scanner in = new Scanner(reader);  
             System.out.println(in.next());
        } catch (FileNotFoundException e) {
            throw new MyException("文件没有找到", e);    //throw
        }  
        
    }




                                                                                                                                            #In fact, there is indeed a lot of discussion about the advantages and disadvantages of using exceptions. For example: http://www.php.cn/

. This blog post has a more in-depth discussion on whether to use exceptions. LZ is really a rookie and cannot understand the extremely profound things. But one thing LZ can be sure of is that exceptions will definitely affect the performance of the system.

         Exception usage guide (excerpted from: Think in java)

        Exceptions should be used in the following situations.

​​ 1. Handle the problem at the appropriate level (catch the exception only when you know how to handle it abnormal).

2. Solve the problem and re-call the method that generated the exception.

3. Make a little patch, and then continue execution bypassing the place where the exception occurred.

4. Use other data to perform calculations to replace the value expected to be returned by the method.

           5. Try to do everything that can be done in the current operating environment. Then the same (different) exception is re-thrown to a higher level.

#6. Terminate the program.

7. Simplify.

8. Make class libraries and programs safer. (This is both a short-term investment for debugging and a long-term investment for the robustness of the program)


The above is the content of Java Improvement Chapter (17)-----Exception (2). For more related content, please pay attention to the PHP Chinese website (www .php.cn)!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn