Translation Exceptions, Don't Cast Your Net Too Widekevin Translation (Participation: 282, Expert Score: 1130) Posted: 2003-10-27 10:11 PM: 2003-12-2 4:24 PM Version: 1.1 Read 2255 times
Excerpted from javaworld, original text, please: when catching exceptions, don't cast your net to wide by Dave Schweisguth http://www.javaresearch.org/Article/showArticle.jsp?column=331&thread=9876 Understanding Java Compiler in compile How do you check the Catch clause. Summary Compared with other languages, Java's simple and consistency allows the compiler to detect many errors. Java developers recognize how to rely on the compiler to capture the incorrect type, the invocation of the non-existing method (the subject of this article) and incorrect abnormal processing. But in what you really need to know what you are doing, the situation you don't want to see will still appear. If you can understand how Java let you throw and capture an exception, then you will know when you need a special care, what habits can make you stay away from the trouble. Java's compile time checks the perfect support for the framework that keeps an unusual security. If a method declaration will throw an exception, you can't use this exception in your method or declare that your method will throw this unusual. Calling that method. (More broad discussion, please see the "Designing With Exception" compiler sometimes stop you from caught an exception that is not thrown in the TRY block, but not always, most of it will. This Java TIP once again discussed the compile period check. The compile period of the throw clause First, let us distinguish how Java checks how the Catch clause captain is an exception that is declared in a method. (In this article, when I started with lowercase letters E, I refer to java.lang.throwable and its subclass. When I want to indicate a clear class, like java.lang.exception I will include the package or at least the class name starting with uppercase letters.) Just start, this method seems to be very similar: both of the two points indicate the exception thrown by the code block. However, when Java requires a method to declare an exception thrown, it does not rely on the requirement that the method throws each statement, Java allows you to design a stable API when you add a function. Look at this one connection pool made from the original version: public class ConnectionPool {public ConnectionPool () throws ConnectionException {} public Connection getConnection () throws ConnectionException {// Allocate a connection (possibly throwing a ConnectionException or a // subclass) if Necessary, the return it}} The constructor does not do, and the code in the getConnection () method may throw an exception of ConnectionException, so in this implementation, the method does not actually declare any exception.
However, the next version, we rewrite this class to improve the getConnection () speed: public class ConnectionPool {public ConnectionPool () throws ConnectionException {// Allocate all the connections we think we'll ever need} public Connection getConnection () THROWS ConnectionException {// Allocate a connection if Necessary (not likely), the reburn it}} Because we write the constructor in the first version declare the connectionException, use its code not to rewrite the use of the second version . Java has checked the throw clause to consistently consistently stability in all other calls of this constructor - this is a good way. Catch clauses of Catch clauses The Catch clause is different from the throw clause. The view of API stability is not applicable: When a method declares is part of a class of common interfaces, a try / catch block is an implementation of the detail from the caller's perspective. Not only did not understand the exception of the TRY block without throwing because a Catch clause was captured, but also guaranteed that it would not be so able to capture a serious code error. For this reason, Java asked your TRY block to do throw an exception that their Catch clause capture. For example, suppose you have a long-term operating system, and write the following small code: public class rm {public static void main (string [] args) {for (int i = 0; i The caller of the method needs to know a Catch clause to a special subclass; this cannot only capture Namingexception. Further, if a method of throwing the Namingexception subclass is changed in later versions, then the original implementation does not need to change, and its caller does not need to change. This flexibility also gives API greater stability. In fact, there will be some small troubles in the Catch clause capture. For example, many readers may have written similar to the following practical methods: public class connectUTIL {/ ** close the connection Silently. Keep Going Even if there is a problem. * / Public static void close (conne {connection.close ();} Catch (Exception E) {// log the message (using the jdk 1.4 logger) and move on logger.global.log (level.warning, "couldn't close connection", e);}}} This program will not be able to appear when the error is turned off, so we just capture and record them. However, remember that runtimeException inherits from Exception. If we capture Exception, as shown in this example, we will also capture runtimeException. A empty connection is passed to this method. It may be a more serious situation than the failure of closing a valid connection - may mean programming errors. If you try to call Close (), you will throw NullPoinGerException. You want this error to spread to your point of view and reach your serious error manager, not a warning error. Is there a solution? Yes, don't capture Exception, but caught special exceptions thrown by the method you are calling. If it throws multiple exceptions, then capture each, or a public superclass (which is not an Exception) should be careful for those common superclars. Capturing Exception is the most common situation, compile checking will make you pass here, have similar situations in capturing any subclasses. You may want to handle java.io.io.eofideXception, just caught Java.ioException, which cannot be captured to distinguish it. In general, if your code handles an exception subclass in the same way, you can only capture this superclass. Errors and running period (runtimeException) can be captured and whether they have been thrown separately, the fact that the CatCH clause can capture the subclasses does not explain why the following code snippet can be compiled, even the only possible throw The unusual code line is also commented: try {// dosomething (); // commented out durning development} catch (exception e) {logger.global.log (level.severe, "something failed", e);} Another confused place is the two unusual use, java.lang. error and java.lang.RuntimeException, which fully avoids the compile period. Catch clauses can capture this exception whether they are actually throw. Java Language Specification (JLS) Explains why these exceptions can be thrown without capturing or declaring: The main reason is the error from JVM (Error) may occur anywhere, and from many language structures The runtime exception may occur anywhere. Checking them will not only increase the difficulty of writing compilers, and will also force programmers to deal with those who don't have to do what they do. Now, we will continue to discuss the check of the CatCH clause. JLS did not expressly point out that Error and RuntimeException can be captured in case of being thrown, but this is the behavior of Sun's compiler (an empty TRY block or only one unusible statement The TRY block can have a Catch clause that captures ERROR or RUNTIMEEXCEPTION). Put it to a piece to observe that now we still don't explain why Exception can be captured, even if it is not clear. Put it to a piece: RuntimeException inherits from Exception, so if RuntimeException can throw anywhere, the Exception can be thrown anywhere. Similarly, Error inherits from Throwable, so although it is throwable, ERROR can be captured whether it is clearly thrown. The logic of this exception inspection rule in Java has led to an embarrassing result. Everyone who is in order to catch the task will take java.lang.exception. You can imagine, the final deadline for the handling is here, and you are working hard for a new tool bag, but it has difficulty counting wrong conditions, and you don't have time to handle them. Even if all the exceptions of the kit have inherited from some common subclasses, you don't want to find them immediately, then in order to make it run, you encapsulate those code in a TRY block that captures Exception. Ha: You just designed a trap for people you want to edit your code. Subsequently, when you refine your prototype code, you may split the huge TRY block. That will result in an exception thrown in that block no longer thrown. In fact, as shown in the above example, even if you don't throw any exception's code at all - but you will not find it from the compiler, because you will catch Exception. That means surrounded by a valuable Try / Catch block, bloated and chaotic code. So if you do not capture the Exception, if you do it, then you have to come back later to fix those CATCH clauses. Sometimes capture Exception is also meaningful. For example, in the final error processor of your application or in the execution engine of an application server, you don't want a code in a service to turn off the entire server. But most of the code does not require this special excellent. Note: IBM's Java Compiler --Jikes - When you don't have a clear statement, you caught it, you will not warn you, like many other terms, not implemented in Sun's compiler. However, when you only throw an exception subclass and you caught its superclass, it will not warn. I don't have enough experience for Jikes to suggest how to use it, but you can easily try it. If you are interested, I still suggest you check it. Best habits Last summary: Java allows you to lose error handling information when capturing exception: You can capture a superclass and lose special information passed by subclasses. Suppose you don't have any exceptions in your code, you will not be told to have any errors when you capture Exception or throwable. So, how can I stay away from trouble? Capture the most special exception as possible. Only when you are confident that all the exceptions you have to capture have the same meaning as your code, you can capture a superclass, and this super class will be thrown in a future version of a method in a new class. Otherwise, if you can always capture Exception or Throwable. If you do not capture Exception or Throwable, consider processing from other Exception or Throwable subclasses. Remember one of the following gold gauge: You should never throw an Exception or Throwable. When reconstructing the improved code, check those who are deleted, check the possibility of throwing exceptions, because the compiler doesn't always tell you. If these guidelines are kept in mind, you can write different unusual code. ========================== Original ========================== ====== Page 1 of 2 Advertisement