I know that try statement is useless without catch or finally, and the finally clause is optional in a try-catch block. However, when I write a try statement without catch or finally, the compiler suggests inserting finally clause to complete try statement.
For example:
try {
for (int j = 0; j <= i.length; j++) {
System.out.println(i[j]);
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Catch");
} //no errors
try {
for (int j = 0; j <= i.length; j++) {
System.out.println(i[j]);
}
} //syntax error
Error code:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Syntax error, insert "Finally" to complete TryStatement
at Driver.main(Driver.java:12)
Why is finally the only recommended statement to implement? Why not catch?
"I might want something to happen despite an exception being thrown, so I may not be looking to handle a specific exception in a specific way, but I may want to ensure that at least SOMETHING generic happens. If I can't handle it, at least do something." Looking for somebody to confirm on this.
Because a try without a catch or a finally makes no sense at all. It just does nothing so you'd have the same result if you just omit the try-block.
It's required that a try statement has either a catch or finally clause because it would make very little sense in having a try statement without it.
The whole idea with the try statement is that there is some kind of handling to be done if the try-block throws exception. This handling can either be to catch an exception (using catch) or do something after the block has finished or an exception has been thrown (using finally). Then to have no such action associated with the try statement makes the try statement pointless.
finally guarantees the code in finally block always execute no matter there's exceptions or not, and you can write cleancode in finally block except handling exceptions, for example close a file or close a socket in it. try-catch is for a caught exception that you can fix it locally.
You cannot have a try not followed by a catch or a finally
In order to fix it add a catch or a finally or both like this:
try{
for(int j = 0; j <= i.length; j++)
{
System.out.println(i[j]);
}
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("Catch");
}//no errors
try{
for(int j = 0; j <= i.length; j++)
{
System.out.println(i[j]);
}
}//syntax error
catch(Exception e) {
// ... handle errors ...
} finally {
// ... cleanup that will execute whether or not an error occurred ...
}
Related
I'm writing a loop that ignored the Exception and it works well.
for (; flag; ) {
try {
//do something ignore exception.
Runnable r = queue.pollFirst();
r.run();
} catch (Exception ignored) {
// ignored.
}
}
But my question is: If I don't catch RuntimeException and force continue loop in finally block, what will happen to the Exception and returned value?
Example:
for (int i = 0; i < 10; i++) {
try {
System.out.println(i);
throw new RuntimeException();
} finally {
//what will happen to the exception if continue loop?
continue;
}
}
They will be ignored as the finally block has the final word.
Runtime Exception will be ignored because there is no catch block to access/use (e.g. for logging purpose) thrown object of java.lang.RuntimeException. finally block does not have any access to Exception object thrown by try block. Its better to have catch block to get more information.
Not sure why you would want to catch a RuntimeException because by the time you even try catching it, it's too late therefore your continue will never hit.
This might be a really dumb question to most of you here, really sorry about that. I am new to java and the book i am reading didn't explain the working of an example in it.
public class CrazyWithZeros
{
public static void main(String[] args)
{
try
{
int answer = divideTheseNumbers(5, 0);
}
catch (Exception e)
{
System.out.println("Tried twice, "
+ "still didn't work!");
}
}
public static int divideTheseNumbers(int a, int b) throws Exception
{
int c;
try
{
c = a / b;
System.out.println("It worked!");
}
catch (Exception e)
{
System.out.println("Didn't work the first time.");
c = a / b;
System.out.println("It worked the second time!");
}
finally
{
System.out.println("Better clean up my mess.");
}
System.out.println("It worked after all.");
return c;
}
}
I can't figure out where the control will go after another exception is generated in catch block in divideTheseNumbers() method ?
Any help will be appreciated !
Output for your program will be
Didn't work the first time.
Better clean up my mess.
Tried twice, still didn't work!
Didn't work the first time. - because of the catch block in divideTheseNumbers
Better clean up my mess. - because of the finally block in divideTheseNumbers
Tried twice, still didn't work! - because of the catch block in the main method.
In general when a exception is thrown from a method and if is not in a try block, it will be thrown to it's calling method.
There are two points to note :
1) Any exception that is not in a try block will be just thrown to
it's calling method(even if it is in a catch block)
2) finally block is always executed.
In your case, you are getting the second exception in catch block, so it will be thrown. But before exiting any method it will also execute finally block(finally block is always executed). That is why Better clean up my mess is also printed.
Some points regarding exception handling:
1. Place your code that may causes exception inside the try{} block.
2. Catch the appropriate exception using the catch block.
3. While catching exception it's better use more specific type exception instead of catching the generic exception like. For example you catch the Exception, in this case you may catch the more specific type exception ArithmeticException.
4. finally block always executed, even though you use return statement in catch or try block.
5. A method either throws or catch an exception. If a method catch an exception then for it is not required to throws the exception.
6. All exception need not to be handled by using catch-block. We can avoid the try-catch block for the unchecked exception like - ArithmeticException,NullPointerException, ArrayIndexOutOfBoundsException. See here for more.
You may also check the tutorial for learning more about exception handling.
Without using finally, how can we execute any compulsory statement even after exception is thrown ??
Furthermore, the variables used or the method has scope only inside the try block. This question was asked by me in a interview. please suggest the answer.
try{
//........ statement 1
// ....... statement 2 might throw an Exception
// ....... statement 3 - A compulsory statement
needs to be executed even if exception is thrown.
}
catch {
}
This is really only academic - if you want a statement to be executed after an exception is thrown, you really should use finally. However, you could catch the exception in a try-catch-block, put your statement inside the catch clause, and then rethrow the exception. Emphasis on could, of course you should not.
/*
* DO NOT DO THIS! (Even if you could.)
*/
try {
//........ statement 1
Exception e = null;
try {
// ....... statement 2 might throw an Exception
} catch (Exception e2) {
e = e2;
}
// ....... statement 3 - A compulsory statement
// needs to be executed even if exception is thrown.
if (e!=null) {
throw e;
}
}
catch {
}
You could be wrapping the problematic part into another catch block and manually manage what finally would do
try{
//........ statement 1
Exception saved = null;
try {
// ....... statement 2 might throw an Exception
} catch (Exception e) {
saved = e;
}
// ....... statement 3 - A compulsory statement
// needs to be executed even if exception is thrown.
if (saved != null) throw saved;
}
catch {
}
That's kind of problematic though since you'd have to catch(Throwable) to get the same effect as finally, and Throwable is a checked exception meaning that you suddenly have to declare it or use dirty tricks: Java SneakyThrow of exceptions, type erasure
What about this:
boolean flag = true;
int firstExecution = 0;
while(flag){
try{
firstExecution++;
if(firstExecution==1){
//........ statement 1
// ....... statement 2 might throw an Exception
}
// ....... statement 3 - A compulsory statement
needs to be executed even if exception is thrown.
flag=false;
}
catch {}
}
And if you want to try to execute statement 2 again and again then you can shift the bracket below statement 2 to above it.
VERY BAD EXAMPLE NEVER DO THIS. USE FINALLY. JAVA DEVELOPERS HAVE DONE SO MUCH TO PROVIDE YOU WITH FINALLY.
try {
// statement 1
try {
// statement 2 ---- might throw an Exception
} catch (Exception e) {
}
// Put your compulsory statement 3 here.
}
catch {
}
This is what i can suggest.
This question already has answers here:
Exception thrown in catch and finally clause
(12 answers)
Closed 9 years ago.
When I am executing following code
1. public class test {
2. public static void main(String[] args) {
3. try {
4. int i = 10 / 0;
5. } catch (Exception e) {
6. int j = 10 / 0;
7. } finally {
8. int k = 10 / 0;
9. }
10. }
11. }
I am getting an error:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at test.main(test.java:8)
I am not getting the reason why JVM is throwing exception from main() and not the catch block.
If you follow the step-by-step description of a try-catch-finally in the JLS, you see that (in summary) if catch throws an exception then finally is executed and (emphasis mine):
If the catch block completes abruptly for reason R, then the finally block is executed.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
So the exception thrown by the catch block (which is executed before the finally block) is discarded and the reported exception is the one thrown in the finally block.
Because in every block - try/catch/finally you have a division by zero. Add another try-catch block inside catch and report an error in catch.
For example:
public class test {
public static void main(String[] args) {
try {
int i = 10 / 0;
} catch (Exception e) {
try {
int j = 10 / 0;
} catch (Exception e) {
// report an error here - do not do any business logic
}
} finally {
int k = 10 / 0;
}
}
}
One interesting thing to note is that, if you comment your code in the finally statement, the ArithmeticException thrown will concern the code in your catch statement.
I believe what's happening here is that the Exception that should be thrown in your catch statement is ignored, because an Exception is thrown in your finally statement.
The exception
in } catch (Exception e) {
int j = 10 / 0;
}
will be thrown to finally block, if you remove finally block, you will got an
Exception in thread "main" java.lang.ArithmeticException: / by zero
at test.main(test.java:6)
All exception in catch block will be thrown to finally block
also finally block will be executed any way
try
{
System.out.println("Try block 1");
int i = 10 / 0; //First Exception
System.out.println("Try block 2");
} catch (Exception e) { //Catched the first Exception
System.out.println("Catch block 1");
int j = 10 / 0; //Again Exception --> Who will catch this one
System.out.println("Catch block 2");
} finally {
System.out.println("finally block 1");
int k = 10 / 0; //Again Exception --> Who will catch this one
System.out.println("finally block 2");
}
If an exception occurs within the try block, that exception is handled by an exception handler associated with it. To associate an exception handler with a try block, you must put a catch block after it.
You associate exception handlers with a try block by providing one or more catch blocks directly after the try block.
Each catch block is an exception handler and handles the type of exception indicated by its argument
The finally block always executes when the try block exits.
In Java Exception Handling, no matter the exception is caught or not, but if you have used finally block, it would always get executed.
Hence, what you are doing in your code is-
Throwing exception object from main()
Catching exception in catch block
Throwing exception caught in catch block to the finally block (it would get executed anyway!)
In this code, either you use only catch or only finally, to get proper result.
and, since you want exception to be caught in catch, omit finally, just use catch.
Good luck!
I want to create a RandomAccessFile object (in Java) and both write to it and read to it. My problem is that, as far I know I seem to need to create the file within a try/catch block. If I try to create it outside a try/catch block and then initialize it within the block like this,
RandomAccessFile valueFile;
try
{
valueFile = new RandomAccessFile("valuefile.txt", "rw");
for (int i=0; i<numOfNums; i++)
valueFile.writeDouble(randomizer.nextDouble()*200);
}
catch (Exception e)
{
System.out.println("Couldn't find the values file.");
System.exit(0);
}
for (int i=0; i<numOfNums; i++)
{
double total = 0;
valueFile.seek(0); // go to beginning of file to start reading it.
}
then I get the error "unreported exception java.io.IOException; must be caught or declared to be thrown". (I also get "variable valueFile might not have been initialized".)
But when I do create it within try/catch, like this,
try
{
RandomAccessFile valueFile = new RandomAccessFile("valuefile.txt", "rw");
for (int i=0; i<numOfNums; i++)
valueFile.writeDouble(randomizer.nextDouble()*200);
}
catch (Exception e)
{
System.out.println("Couldn't find the values file.");
System.exit(0);
}
for (int i=0; i<numOfNums; i++)
{
double total = 0;
valueFile.seek(0);
}
I get "cannot find symbol: variable valueFile" on the later part of the program. I presume that that's because valueFile is considered local to the try/catch block? But then how do I create valueFile so it's not local to the try/catch block?
I think your first approach was correct. The error isn't being caused by the file creation, but rather by the valueFile.seek(0); call. This can also throw an IO Exception, so you need it in a try/catch block as well.
Edit: As Jon pointed out, your code still won't compile since valueFile might be uninitialized. Just initialize it to null and it will work.
RandomAccessFile valueFile = null;
You could instead use one of the methods described in Jon's answer to convince the compiler that valueFile is actually initialized by the time it gets to valueFile.seek(0). His method is safer, but just initializing to null is a nice quick fix so that you don't have to clutter your code with unreachable throw statements.
However, I think it would be even better if you just move the declaration, initialization with the new RandomAccessFile and all accesses to the file within the same try block. I can't think of any good reason to split them up.
The first version is nearly right - but there are two problems:
Your method doesn't declare that it can throw IOException, but your use of valueFile.seek could throw an exception. Either you need to change the method declaration, or catch and handle the exception.
The compiler doesn't know that System.exit(0) will never return normally - it thinks it's a normal method. So you have to change your catch block to end with something like:
return;
or
throw new AssertionError("We'll never get here.");
At that point, the compiler knows that if it gets beyond the try/catch block, valueFile is definitely assigned.
Note that if you move everything inside the catch block, both problems will go away - but I'd suggest that you'd be better off not catching anything at all, and instead just declaring that the method may throw IOException:
public void foo(int iterations) throws IOException {
RandomAccessFile valueFile = new RandomAccessFile("valuefile.txt", "rw");
for (int i = 0; i < iterations; i++) {
valueFile.writeDouble(randomizer.nextDouble()*200);
}
for (int i = 0; i< iterations; i++) {
double total = 0;
valueFile.seek(0);
// Presumably you'd read the contents here?
}
}
... except you should also close the file when you're done with it, using a try-with-resources statement if you're using Java 7, or just a try/finally block otherwise.
RandomAccessFile valueFile;
needs to be:
RandomAccessFile valueFile = null;
(I also get "variable valueFile might not have been initialized".)
To fix the above.
Declare the variable outside of the try catch block and then load from within it.
RandomAccessFile valueFile;
try
{
valueFile = new RandomAccessFile("valuefile.txt", "rw");
for (int i=0; i<numOfNums; i++)
valueFile.writeDouble(randomizer.nextDouble()*200);
}