I am having issues understanding what happens when an exception gets thrown.
What happens to the exception that is thrown? What handles it to ensure that the program does not crash?
For instance, in this example from this tutorial, what will deal with the ArithmeticException that is thrown?
static int remainder(int dividend, int divisor)
throws DivideByZeroException {
try {
return dividend % divisor;
}
catch (ArithmeticException e) {
throw new DivideByZeroException();
}
}
The tutorial you link to emphasizes an important difference in what types of exceptions there are in Java, namely, whether an exception is checked or unchecked.
A checked exception is one that requires you as the developer to either catch it (i.e. deal with it), or declare it to be thrown and dealt with upstream. The expectation is that you can recover from these sorts of exceptions.
An unchecked exception is one that may or may not crop up during the natural execution of the application, and may not introduce a natural way for the application to recover. Catching them is often frowned upon since it is often indicative of poor design (you allowed a zero to make its way to a division operation, that's an illegal argument!).
In this scenario, because the method remainder declares that it is throwing a DivideByZeroException, all upstream callers of it must handle its exception either by:
public static void main(String[] args) {
try {
NitPickyMath.remainder(1, 0);
} catch (DivideByZeroException e) {
e.printStackTrace();
}
}
...or by:
public static void main(String[] args) throws DivideByZeroException {
NitPickyMath.remainder(1, 0);
}
The caveat to the latter form is that nothing will deal with the exception, and it will cause the application to crash.
...what will deal with the ArithmeticException that is thrown?
You already are dealing with it by placing it in a catch block. You're simply re-throwing a checked exception to deal with the actual error resulting from dividing 1 into 0.
Related
By "method exit" - I mean the actions in a method such as return or throw new... that the compiler considers the end of a method - if you could please tell me the accepted word for "method exit", I will edit the question
My problem is the following:
I do a lot of throw new RuntimeException(...
So, I decided to "tuck it in" as:
public static void quickRaise (String msg) { throw new RuntimeException(msg); }
And then I can reuse it.
(This will help me in the future to enhance the procedure around raising Runtime Exceptions and even
switch to a custom Exception class, without fishing in the code for exception throws)
However, where before I could write:
public MyType doSomething() {
try {
//...
return new MyType (parameter);
} catch (Exception e) {
throw new RuntimeException("msg")
}
}
And the compiler would correctly understand that "this method either exits by return or by throw" and therefore there are no logical "dead ends"
When I changed throw new RuntimeException("msg") to quickRaise("msg"), the compiler no longer considers my method "complete". It complains about a missing return statement, even though quickRaise is semantically equivalent to throw (or at least this is what I am trying to do!)
Let me try to reiterate the problem by a reproductive example (this will not compile, which is the problem):
public static void main(String[] args) {
System.out.println(doSomething());
}
public static String doSomething () {
try {
//... Some fun stuff going on here
return "Something";
} catch (Exception e) {
quickRaise("Could not find handshakes");
//throw new RuntimeException("If you uncomment this line, it will compile!");
}
}
public static void quickRaise (String msg) {
throw new RuntimeException(msg);
}
Your idea is highly inadvisable.
For example, this is just bad codestyle:
try {
someIO();
} catch (IOException e) {
throw new RuntimeException("Problem with IO");
}
The reason it's bad is that you have now obliterated the actual information about the problem. That information is locked into 5 separate parts of that exception you just caught: Its type (for example, FileNotFoundException, its message (e.g. "Directory /foo/bar does not exist"), its stack trace, its causal chain, and as throwables are objects, any particular extra detail for that particular kind of exception (such as the DB-engine-specific error coding for some SQLException).
Throwing this info away is silly.
All you'd need to do to fix this, is to add the cause:
} catch (IOException e) {
throw new RuntimeException("IO problem", e);
}
Now the IOException is marked as the cause of the exception you are throwing, which means in error logs you'll see it + the message + the stack trace of it + the stack trace of any causes it had as well.
All you need to do to make the compiler realize that the method ends here, is to throw it:
public static RuntimeException quickRaise(String msg) {
throw new RuntimeException(msg);
return null; // doesn't matter, we never get here
}
// to use:
throw quickRaise(msg);
But, as I explained before, this is a very bad idea.
Secondarily, having the idea of 'I just want to throw an exception and maybe later I want to replace the kind of exception I throw' also doesn't really work out: You need to pick a proper exception for the situation, therefore you cannot write a one-size-fits-all throw method in the first place.
Okay, so what do I do?
Primarily, learn to embrace throws clauses. If your method fundamentally does I/O (for example, the javadoc of it and/or the name makes that obvious, it is for example saveGame(Path p), or scanUserHome), then it should be declared to throws IOException.
If your method is an entrypoint (as in, it is the first point where your own code begins running), then your method should be declared to throws Exception. For example, your public static void main() method should throws Exception. Sometimes an entrypoint isn't main but something else (a webhandler routing hook for example), and sometimes backwards silly franeworks prevent you from doing that, but there tends to be a wrap functionality (such as } catch (Exception e) { throw new ServletException(e); }).
For exceptions which are both [A] fundamentally not part of the method's purpose, but more part of an implementation detail and [B] is very unlikely to go wrong and there's not much you can do other than hard crash if it would, then, yeah, rewrap as RuntimeException. There isn't a lot of point in ever changing this 'globally' for all such exceptions. At best you belatedly realize that failure is a bit more likely than you originally thought and either create a proper exception for it and document this behaviour. But that's, again, on a per-method basis, not something you can apply in blanket fashion.
Your approach is fundamentally at odds with the need for the compiler to see that the flow terminates at the throw statement.
I'd suggest having a utility method that just constructs an exception, which you then throw from the original point.
It's either than or put dummy returns after each call to quickRaise().
This question already has answers here:
Exception handling : throw, throws and Throwable
(8 answers)
Closed 6 years ago.
I am confused to get a clear understanding of when throw is used and throws is used. Kindly provide me an example to show the difference.
Also, I tried the below code:
package AccessModifiers;
//import java.io.IOException;
public class ThrowExceptions {
int QAAutoLevel;
int QAExp;
void QAAutomationHiring(int grade)
{
if (grade<5)
throw new ArithmeticException("Not professionally Qualified");
else
System.out.println("Ready to be test");
}
void QAExperience(int x,int grade)
{
QAAutomationHiring(grade);
}
void checkThrowsExep(int a,int b) throws ArithmeticException
{
try{
int result=a/b;
System.out.println("Result is :"+result);
}
catch(Exception e)
{
System.out.println("The error messgae is: "+ e.getMessage());
}
}
public static void main(String args[])
{
ThrowExceptions t=new ThrowExceptions();
//t.QAAutomationHiring(8);
t.QAExperience(2,8);
t.QAExperience(4,2);
t.checkThrowsExep(5, 0);
}
}
In the above code, when I run the program, the line- 't.checkThrowsExp' in main function is not reached. I studied that throw and throws are used to catch the exception and continue with the program execution. But here the execution stops and not proceeding to the next set of statements. Please share your comments.
throws is used to tell people that
Warning: this method/constructor has a high chance of throwing XXXException and YYYException! Please make sure you handle them!
Example:
The Thread.sleep method is declared as:
public static native void sleep(long millis) throws InterruptedException;
As you can see, the throws keyword tells people that sleep is very likely to throw an InterruptedException. Because of this, you must surround the method call with try-catch or mark the caller method with throws InterruptedException. The exceptions after the throws keyword are usually "checked" exceptions which are caused by invalid conditions in areas outside the immediate control of the program, like invalid user inputs, database problems etc.
Please note that it is possible for a method marked with throws XXXExcepion to never throw XXXException.
throw, on the other hand, actually throws the exception. It can be used like
throw new RuntimeException("Something went wrong!");
And whenever code execution reaches this statement, an exception will be thrown no matter what, and the method returns.
In short, throw actually does the throwing, and throws is only saying that an exception will likely be thrown (which in fact, be wrong).
Throw actually returns the exception whereas throws is a sign to the compiler, that this method could return an exception.
In your code above the exception ArithmeticException will be created and returned, if the grade is lower than 5, which is the case in your second call of QAExperience.
As the calling method called the method, which returned the exception, is not insede a catch block it will also just stop its execution and return to the main method. As the main method also does not catch the exception it will just like the others stop its execution and return the exception. This is the reason, why t.checkThrowsExp will not be executed.
Is it correct, safe and sane to throw an exception after a successful retry? Which programming principle is violated in this example?
class B {
private int total;
public void add(int amount) throws Exception {
if (amount < 0) {
throw new Exception("Amount is negative");
}
total += amount;
}
}
class A {
public B b = new B();
public void addToB(int amount) throws Exception {
try {
b.add(amount);
} catch (Exception ex) {
try {
b.add(-amount);
} catch (Exception ex2) {
}
throw new Exception("Amount was negative. It was inverted and then added.");
}
}
}
your code is working but since you are calling a addToB() method which throws exception inside a catch block you must implement another try-catch block within try-catch block. and at the end you are throwing a exception even after having so many try-catch blocks which is not good since the exceptions if not handled can cause problems and its very bad practise to throw exception if the method was success. i see that you need the user to know what happened inside the method, you can return a string from the
method which will tell the user what happened inside the method.
ex: -
public String addToB(int amount){
String msg = "";
try{
b.add(amount);
msg ="successful";
}catch(Exception ex){
try{
b.add(-amount);
}catch(Exception ex2){
}
msg= "Amount was negative. It was inverted and then added.";
}
return msg;
}
even this is not the best practise bt you might need check this.
There are a few sound principles that you are violating.
Throwing java.lang.Exception is bad in such situations (or in general), even if you are writing toy code. You should consider using a RuntimeException. The idea is pretty simple. You know nothing about the amt until you run the program. If a user or client of this code provides negative argument, then it an unexpected argument only to be known at runtime. Do not promote the Pokemon exception handling anti-pattern.
You are utilizing the baklava code pattern. This should be avoided.
The more serious error you are committing is doing the thing anyway exceptionally or not. Here's a use of your classes:
public static void main(String[] args) {
A a = null;
try {
a = new A();
a.addToB(10); // no exception here, total should be 10
a.addToB(-10);
} catch (Exception e) {
// exception here, but the total should be 20, or not?
System.out.println(a.getTotalFromB());
}
}
Now, in this case, the value of total is 20 even when an exception was thrown! Almost always, exceptions should be used to signal exceptional conditions where the expected things do not happen. This, to me, is a serious violation.
It's possible to do this, but this is a bad idea for three reasons:
You're using exceptions as control flow. This is an antipattern which is to be avoided.
You're throwing Exception. If this is truly exceptional behavior, then you should look to create your own [checked] exception type.
You're catching Exception in that block. If b is null then you're not guaranteed that the input was invalid at all.
Let's start with the flow.
In this scenario, it doesn't make immediate sense why a negative value is considered exceptional enough to recover from, which is what the checked exception implies.
Effectively, if the first attempt seems to fail with a negative number, the idea is to try it again by negating the negative, resulting in a positive number.
Something like this can be mitigated in several ways, depending on what the negative value means to the business:
Throwing multiple exceptions (least preferred)
Silently drop it, but log the value passed in (less preferred)
Throw an unchecked exception and do not require its callers to catch it (preferred)
With my preference, the code above would look like this:
public void add(int amount) {
if(amount < 0)
throw new IllegalArgumentException("Amount may not be negative");
total += amount;
}
This would put the onus of ensuring that the input is correct and appropriate for this method on the developer as opposed to the application. Unit tests here would go a long way to ensure the behavior that you want.
Now, to throwing Exception: Exception is checked meaning that everyone has to catch it or declare it to be thrown, which is unpleasant to code.
Checked exceptions should be reserved for something that the user can do to recover from (for instance, FileNotFoundException - user should be sure that the file path is correct).
Lastly - you should not be catching Exception. That's too broad of an exception to catch, considering that b may be null.
--the effects of case 1 and 2 are the same, why need to add the exception declaration in method signature?
//case 1
public void doSomething() throws Exception {
//do Something
}
public void Caller() {
try {
doSomething();
} catch (Exception e) {
//handle the exception
}
}
//case 2
public void doSomething() {
//do Something
}
public void Caller() {
try {
doSomething();
} catch (Exception e) {
//handle the exception
}
}
reference:
what is the use of throws Exception
The throws declaration is used to declare which checked exceptions your method throws.
For instance, if I write this code:
public void doSomething() throws SQLException {
}
any code that calls this method must have a try/catch block for SQLException, Exception, or Throwable... or it can have its own throws declaration for one of those 3.
In this case, there is no difference, except that you're alerting the compiler to an exception that you're not going to be throwing.
It's also a bad idea to catch throw "Exception" - in both cases, you want to deal a particular exception that has a particular meaning. When you're catching, the only reason to use a try block is if you expect a particular exception, so you should catch that one. This way, if some unexpected exception comes up, you don't try to handle it the wrong way. (instead, your program fails, and you know there's a condition you have to deal with) When you're throwing, you want to throw a particular exception, either one you make up, or a standard one that has a known meaning, so the calling function knows what to deal with. For example, if your doSomething might throw an ArrayIndexNotFoundException if the widgets are not frobnicated, you might want to catch the ArrayIndexNotFoundException and throw a WidgetNotFrobnicatedException. Any time you throw an exception, your javadoc should specify exactly what circumstances will trigger that issue, so the user of your code has a chance to address this possible failure.
(there is one circumstance when I can see catching Exception, and that's if you want to fade to some graceful halt if things go wrong unexpectedly - in that case, in your catch block you'd log the issue, possibly alert a developer, and throw up some sort of "Sorry, error number 3542 has occurred, please restart the program" message.)
If your doSomething method, has the chance to throw an exception and you don't want to catch it, you should add this throws Exception on the method.
Unless it's an exception that you want to handle immediately in that method, it's good practice to use throws [specific Exception] so that the exception can be handled further up in the code.
It's somewhat commonplace to have a generic Throwable catch at the top that "gracefully crashes" in case something goes wrong.
Assuming that the Exception we are throwing is checked, is it compulsory to add throws in a method declaration whenever we use throw inside the method?
Any checked exception (e.g., one which does not extend RuntimeException) that might escape a method needs to be declared in the method signature. For example:
public static void mightThrow(String s) throws NumberFormatException {
// ...
int x = Integer.parseInt(s);
// ...
}
Even though we do not throw any exceptions directly, Integer.parseInt() might throw a checked NumberFormatException. Since we call that method, and we do not catch the potential exception, then our method must also declare the exeception in its throws signature.
This does not necessarily mean that every method that throws (or might throw) a checked exception must declare throws in its signature. If the thrown exception is always caught within that method, it need not be added to the signature. For example:
public static Integer tryParseInteger(final String s) {
try {
return Integer.parseInt(s);
}
catch (NumberFormatException ignored) {
return null;
}
}
In this example, we will always catch any NumberFormatException that might be thrown by Integer.parseInt() and prevent it from bubbling up the stack, so we do not need to declare it in our tryParseInteger() method.
Unchecked exceptions never need to be declared:
public static void unsupported() {
throw new UnsupportedOperationException(
"The specified operation is not supported."
);
}
Here, because UnsupportedOperationException derives from the unchecked RuntimeException, it does not need to be declared.
No, since you may want to throw a exception but handle it in the same place, aka method
The Throws simply let javac know that this method might cause this kind of exception. It is not always necessary. It's useful when you know that a specific method can throw some sort of exception.
Generally speaking, Java is exception-strict, so you have to specific what types of exceptions a method throws. Note that you can use inheritance to simplify your methods' signatures. E.g., you can declare your method as throws IOException, and within its implementation throw any type of IOException you want such as FileNotFoundExeption, InteruptedIOException, etc.
One exception (no pun intended) to this rule are RuntimeExceptions (such as OutOfMemoryError or UnsupportedOperationException) which can be thrown without having to declare them.
Differences:
1) You can declare multiple exception thrown by method in throws keyword by separating them in common e.g. throws IOException, ArrayIndexBoundException etc, while you can only throw one instance of exception using throw keyword e.g. throw new IOException("not able to open connection").
2) throws keyword gives a method flexibility of throwing an Exception rather than handling it. with throws keyword in method
signature a method suggesting its caller to prepare for Exception declared in throws clause, specially in case of checked Exception and provide sufficient handling of them. On the other hand throw keyword transfer control of execution to caller by throwing an instance of Exception. throw keyword can also be used in place of return as shown in below example:
private static boolean shutdown() {
throw new UnsupportedOperationException("Not yet implemented");
}
as in below method shutdown should return boolean but having throw in place compiler understand that this method will always throw exception .
3) throws keyword cannot be used anywhere exception method signature while throw keyword can be used inside method or static initializer block provided sufficient exception handling as shown in example.
static{
try {
throw new Exception("Not able to initialized");
} catch (Exception ex) {
Logger.getLogger(ExceptionTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
4) throw keyword can also be used to break a switch statement without using break keyword.
int number = 5;
switch(number){
case 1:
throw new RuntimeException("Exception number 1");
case 2:
throw new RuntimeException("Exception number 2");
}