K
Exceptions are a form of deviation, as well as ifs, breaks, returns, etc. Its usefulness is to allow a code to be stopped if it has no conditions to continue, conveniently and organizedly.Suppose Java has no exceptions. If the method a calls the method b, who calls c that calls FileReader.read, what happens if there is an error in reading?The method c You have to stop because you can't keep going without the data read. He returns;The method b must know that the method c failed; for that, c has to return a special error code - interfering in your normal return value - and b have to test for this code using one if (e.g.);The method a must know that the method b failed; etc.Somewhere, this error will have to be dealt with - even if it is in main (or Thread.run), to abort the program with error code. What exceptions do is allow the execution flow to deviate [almost] directly from the exact point where the error treatment is possible, without the programmer having to do anything else. More: they collect and store various information about the error, as which methods were running and in which line they were, allowing to generate a report that allows the programmer to more easily discover its cause.When declaring an object, if the programmer predicts that a failure in the execution of the method may occur, it will launch a type object Exception. (right?)Not necessarily. It can do this if the error is detected by its own logic, and this deviation is convenient for the caller. It may also not release exceptions directly, but allow your code (i.e. the other functions that this method calls) to launch them - declaring this in your subscription if necessary (throws ExceçãoX, ExceçãoY). Or he can do something else, like returning an error code, try to treat the exception alone, log somewhere... Depends on the case.In general, the "right thing" to do is to throw/allow an exception even - perhaps unchecked (more on this ahead). Returning an error code complicates the call form, and logging the error makes system customization harder (i.e. if you do not want that this error is logged in, and the method does alone, by its default, this can hinder its use or require some "gambiarra" to circumvent/undo it. If you have no good reason to divert it, do not deviate: use exceptions even.I wanted to understand how the capture and release of the exception works.Returning to the Methods Example a, b and c, say a is prepared to treat the exception E, while b It's not. As the methods are being called, the execution contexts (i.e. local variables, current instruction, etc.) of them are being placed in the pile. Usually, b would have to run until the end before the control returns to a, the same for c in relation to b. But if c finds this exceptional condition - and decides to launch E - The following happens:c creates an instance of the object E, passing the parameters you need;The flow of execution c is interrupted where it is, i.e. your code does not finish running;If c has a block try/finally or try/catch/finally, and the exception was released within try, he performs the finally;c It's a mess. Usually, b I would continue to run where it stopped, but that's not what happens. The exception release process has not yet ended.If b has a block try/finally or try/catch/finally, and c was called inside try, he performs the finally;b It's a mess. Usually, a would continue running from where it stopped, but the process of release of the exception has not yet finished.How b was called inside a block try/catch or try/catch/finally, and E is present in one of the clauses catch, this block is executed.The exception release process is over. The code continues from the block catch forward.Why the RuntimeException and their subclasses are not verified by the compiler.There are two types of exception: checks (Check) and not checked (unchecked). Ideally - from the point of view of Java designers - no method should behave unexpectedly; or it should succeed, or fail in an orderly and consistent manner. As methods usually call other methods, each should be responsible for behave well even in the presence of errors in the methods called. Thus, each method would need to be aware of the exceptions that its components may release, and or treat them or propose them to the caller method. For this to be possible, the caller method has to be aware that this method can release exceptions X, Y and Z, and prepare accordingly.In theory it is a beauty, but in practice this is inviable. There are errors that can occur in any method, and it would be a waste to be declaring them all the time. JVM's memory may end, for example. Or in a division, the divider can be zero. If we were to take into account all these possibilities, the signature of our methods would become gigantic! And to make things worse, it is very unlikely that the caller method will be able to recover from, say, a OutOfMemoryError - anything he tried to do would spend more memory and generate others OutOfMemoryErrorTurning a snowball...That is why there are exceptions unchecked: for disobey the methods of declaring that this exception is possible, but still allow any of them to try to treat it if they think it gives account. A RuntimeException is the base class for all of them except for Error - which generally denotes a more serious condition that can hardly be treated by any method.Note: it is better to use exceptions Check (that inherited from Exception) or unchecked (that inherited from RuntimeException)? I can't tell you. It is a balance between the security of the code and its concision/expressivity. try/catchis too much and your code becomes unreadable, try/catches of less and no one knows more than errors can occur in a method. It is a situation similar to static typing (with or without generic types) vs. duck typing vs. Dynamic typing: gains on one side and gets lost on the other. .If the try/catch block is used only to treat exceptions or if there is other purpose of use.Theoretically you could [ab]use it to simulate a goto, but in general not, it's just to treat exceptions even. It should be noted that in Java the treatment of exceptions is relatively expensive, so that it is often preferable to use "normal" control streams even [for non-exceptional codes], even if this complifies a little your code. Other languages (e.g. Python) already use them for more common situations - for example the idiom (idiom) "do not check the parameters before calling the function, simply call it and if you are not successful capture the exception". It should be avoided in Java (even why try/catches are not exactly concise in my opinion...).Already try/finally and try/catch/finally, is also used to deal with exceptions, even if not exactly to "treatment them". Consider this code:try {
String linha = leitor.readLine();
int x = Integer.parseInt(linha);
}
catch(IOException ioe) { ... }
finally {
leitor.close();
}
In this case, we want the reader to be closed no matter what happens: if the code succeeds, if it launches a IOException, or if he throws any other exception. The important thing is not to forget it open. For even if one NumberFormatException for released on try, and he doesn't even get into catch, finally will still perform (before the exception propagates to the caller method)....and in the case of a multi-exceptional method?As already said, the code of try (or all method code if the exception occurs outside of one try) is interrupted when an exception occurs, jumping to a catch or one finally. If he falls in one catch, then it is considered that the treatment of the exception was done successfully, and the block code catch is treated as a normal code - and can even throw another exception, without any relation with the original exception.If he falls in one finally, on the other hand, we have a problem: finally is not the "destination" of the exception, only a "stop point". If he also produce an error, what should go pro method caller - the original or the new? The solution Java gives to this impasse is the following: the new method is released, but the exception holds a reference to the original exception. It is said in this case that the exception B was "caused by" the exception A. You can access A through B.getCause(). In this case, it is important to emphasize that the caller method needs to treat B - if he just takes care of A, the execution will not enter the block catch.And lastly what is the class Throwable?As already said, there are two types of "errors" in Java: Errors Exceptions. The class Throwable is the superclass of both, created to allow code to treat both simultaneously. "normal" programmers in general should not try to treat Error - since it is a serious failure that will only be circumvented if you know what you are doing well. So there is no sense in using catch Throwable - it is better to take only Exception even (if it is a generic error treatment code) or, better yet, take only the exceptions you can even treat (and propagate all the rest).Some references: http://docs.oracle.com/javase/tutorial/essential/exceptions/chained.html (on exceptions caused by other exceptions) http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html (on use or not exceptions unchecked in its code - obviously, Java authors hang on the security side to the detriment of the concision; others disagree)