Consider this code:
final MyClass myObject;
try {
myObject = new MyClass(...)
} catch (MyClassException){
// terminate
System.exit(1);
}
myObject.doSomething();
The problem is that the Netbeans editor / parser thinks that .doSomething() could be called on an unitialised object which, of course, is not the case.
Is there an normal / standard pattern for circumventing this? I could call into a function but would rather not do that. I'd also rather not enclose the whole block in the try catch block since nothing else throws MyClassException
I'm not (yet ;-) ) an expert on Java grammar and patterns so am hope I'm missing something obvious.
You initialize your object in try block, which may throw exception, leaving object uninitialized.
In your catch block, you stop your program, but System.exit(1) does not stop method execution, instead, it terminates currently running JVM - and for compiler it's just another method you call if an exception is thrown.
return actually stops method execution - so no code beyond return; is reached.
You can modify your catch block as following:
catch (MyClassException){
// terminate
System.exit(1);
return;
}
Compiler won't complain about myObject not being initialized this way.
EDIT
NB: if you put myObject.doSomething(); in finally block compiler WILL complain, since finally is executed even after return.
finally {
// compiler error
myObject.doSomething();
}
The case is that outside the try/catch block you try to call a method on a possibly not instantiated object. That is because the try/catch block may throw exceptions so the object is not created, therefore in this case you will not have an object when you try to call the doSomething() method on it.
If you include the method call in the try/catch block, it will work.
You can find related information here:
Java Tutorials: Lesson: Exceptions
Netbeans editor / parser thinks that .doSomething() could be called on an unitialised object which, of course, is not the case.
You are wrong here. You are in fact trying to initialize the variable. The compiler doesn't "trust" in the initialization and the reason is simple: it could throw an exception, which you could catch but not throw a new RuntimeException() or make a System.exit(1). For example:
try {
myObject = new MyClass(...)
} catch (MyClassException e){
// hey I catch this but do nothing lmao yolo
e.printStackTrace();
}
myObject.doSomething();
you could catch the exception, print the stacktrace and continue the program, and the consequence would be a NullPointerException.
This is the best I can do:
final MyClass myObject;
{
MyClass local = null;
try {
local = new MyClass(...)
} catch (MyClassException){
// terminate
System.exit(1);
}
myObject = local;
}
myObject.doSomething();
The problem is that the Netbeans editor / parser thinks that .doSomething() could be called on an unitialised object which, of course, is not the case.
It is the case: nothing prevents you from using a SecurityManager which will forbid System.exit() from exiting the JVM. In that situation, the next statement could be executed.
From a Java grammar perspective, the compiler needs to prove that myObject is definitely assigned when you call myObject.doSomething();.
The JLS specifies the situations in which this can be done. In particular, the only statements that can be used to determine that the next instruction(s) will not be executed are break, continue, return, and throw. So the compiler is not allowed to consider that System.exit(1); will prevent the next statement from being executed.
The point of the final variables and members is to always be initialized. Although your code will never call doSomething, it will leave the final field undefined. This becomes an issue if you add a finally clause to the try-catch block - you may enter the finally clause when exception occurs and the myObject will not be available, which the compiler must avoid.
final MyClass myObject;
try {
myObject = new MyClass(...); // constructor may throw exception
} catch (MyClassException){
// terminate
System.exit(1);
} finally {
// what does myObject point to now, if the constructor threw exception?
}
myObject.doSomething();
A quick solution is to move the doSomething call in the try block:
final MyClass myObject;
try {
myObject = new MyClass(...);
myObject.doSomething();
} catch (MyClassException){
// terminate
System.exit(1);
}
This should work fine as long as doSomething does not also throw a MyClassException. If it throws such exception, you probably need to differentiate the case whether it came from the constructor or the method (if of course this matters to your logic).
Related
I am trying to follow this tutorial JUnit 5: How to assert an exception is thrown?
I use Java 10, IntelliJ 2018 and Junit 5.
I make a calculator app that adds 2 fractions. It checks whether the input has 0 in the denominator.
When I run the test The exception Message get printed out "Undefined Math Expression" but my IDE says "Expected java.lang.Throwable to be thrown, but nothing was thrown." I think there is some problem with the scope of my code? I'm a newbie, please be kind. I provided the code and the test below:
public class Calculator {
public static int[] calculate (int firstNumerator, int firstDenominator, int secondNumerator, int secondDenominator) {
String exceptionMessage = "Undefined Math Expression";
int resultNumerator;
int resultDenominator;
int[] result = new int[2];
resultNumerator = (firstNumerator * secondDenominator) +
(secondNumerator * firstDenominator);
resultDenominator = firstDenominator * secondDenominator;
try {
if (resultDenominator == 0) {
throw (new Throwable(exceptionMessage));
} else {
result[0] = resultNumerator;
result[1] = resultDenominator;
}
} catch (Throwable e) {
System.out.println(e.getMessage());
}
return result;
}
}
The test:
class CalculatorTest {
#Test
void denominatorContainsZero() {
assertThrows(Throwable.class, () -> {
Calculator.calculate(0,0,0,0);
});
}
}
The misunderstanding here appears to be in what JUnit can actually see.
JUnit isn't magical: it's just plain old Java. It can't see inside your methods to see what they are doing. All it can see is what any other code can see when it executes a method: the return value and uncaught exceptions (as well as any side effects of the method, if they are visible to the calling code).
Your method here doesn't throw an exception from the perspective of a caller: internally, it throws the exception, but it catches and handles it.
If you want JUnit to test that an exception is thrown, you need to not catch that exception.
It is never (*) the right thing to do to throw an exception and then catch and handle it yourself. What's the point? You can simply do the thing you do to handle it, without throwing the exception. Exceptions are expensive to throw, because of the need to capture the entire stack trace.
Throwable is never (*) the right exception to throw. It's the exception "equivalent" of returning Object: it conveys no type information about the exception to the caller, who then either has to do a lot of work to try to handle it; or, more realistically, should just propagate it themselves. IllegalArgumentException is the right exception to throw here, if you actually needed to throw (and not catch) an exception.
Throwable is rarely the right thing to catch. Throwable is a supertype of both Exception and Error, so you might unintentionally catch an Error, like OutOfMemoryError, which shouldn't be caught because there is nothing reasonable to do except crash your program. Catch the most specific type you can; which also means that you should throw the most specific type you can (or, at least, a type appropriate to the abstraction).
(*) This is "never" as in "ok, there are a limited number of circumstances where it may be appropriate". But unless you understand what these are, don't.
The Throwable is catched by try catch block, so Junit can not access it. Try remove the try catch block.
You are not actually throwing exception, you are catching it. For this to work, you should remove try catch block.
As mentionend in the Subject: Java forces me to return something, because the handling of the Exception is in an own function.
public String returnLel(String mattDamon) {
try {
trick(mattDamon); // The LelException could be thrown
return "lel";
} catch (LelException e) {
handleException();
}
}
public void handleException() {
throw new RuntimeException();
}
`
Your code will not compile because the compiler is not "clever" enough to know you are throwing a RuntimeException in handleException.
In order for your code to compile you can either:
directly throw new RuntimeException(); in your catch statement (ugly)
return null after invoking handleException(); (acceptable, but still kind of ugly)
add a finally statement to finalize your method and return null or whatever if some condition has not been met (recommended)
Also note that I'm assuming LelException extends RuntimeException, otherwise your catch statement won't compile.
Well it is up to you on how you will handle the situation.
If you are able to handle the exception by say logging it and just return null as most of the comments imply that is totally o.k.
Just consider that this situation could also mean that the method "returnLel" might not be the correct place to handle this exception but to let the caller decide what to do in this situation by "throwing it further" like so:
public String returnLel(String mattDamon) throws LelException{
trick(mattDamon); // The LelException could be thrown
return "lel";
}
This means if the caller calls your returnLel-Method he will have to try/catch the Exception (or throw it further up) and could in this case mean a better design because the caller will not receive null or a String' but aStringor aLeLException` instead
Move the return statement out of the try catch.
The try block should surround the part where an exception could be thrown, what the return statement not does.
Here the java tutorials for some basic knowledge about this topic:
The try Block
The catch Block
The finally Block
I'm not familiar with java and I've been recently looking at some code written by some colleagues that's baffling me. Here's the gist of it:
public response newStuff(//random data inside) {
try {
response or = //gives it a value
log.info(or.toString());
return or;
}
catch ( Exception e) {
e.printStackTrace();
}
finally {
return null;
}
}
Is there really any point in adding a finally block here? Couldn't I just add the return null inside the catch block, which would execute the same behavior, or am I wrong?
Is there really any point in adding a finally block here?
The answer to this is a resounding "no": putting a return statement in the finally block is a very bad idea.
I just add the return null inside the catch block, which would execute the same behavior, or am I wrong?
It wouldn't match the original behavior, but that's a good thing, because it would fix it. Rather than returning null unconditionally the way the original code does, the code with the return inside the catch block would return null only on errors. In other words, the value returned in the try branch would be returned to the caller unless there is an exception.
Moreover, if you add return null after the catch block, you would see the correct effect of returning null on exception. I would go even further, and put a single return in the method, like this:
response or = null;
try {
or = //gives it a value
log.info(or.toString());
} catch ( Exception e) {
e.printStackTrace();
}
return or;
Actually, no. Finally is (nearly) always run, no matter what the result in the try-catch block; so this block always returns null. Here, look at this example:
public class Finally {
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(finallyTester(true));
System.out.println(finallyTester(false));
}
public static String finallyTester(boolean succeed) {
try {
if(succeed) {
return "a";
} else {
throw new Exception("b");
}
} catch(Exception e) {
return "b";
} finally {
return "c";
}
}
}
It will print "c" both times.
The above mentioned exception to the rule would be if the thread itself is interrupted; e.g. by System.exit(). This is however a rare thing to happen.
The finally is always executed no matter what, and normally can be used to close sessions, etc.
Don't put returns inside a finally block.
This looks like a very bad practice. In this case your code will always return null.
The finally block is called last after the try-catch block runs. No matter if the try finished or the exception block was called. In this case, no matter which path of code is ran, you will always return null.
In the "normal" case where you put the return null after the finally there's indeed a chance to return something (either from the try or from the catch block) and if no flow yields a return object, you fall back to the return null, but you don't always return null.
I've read that a lot of people simply answer "don't use return in a finally block", without any explanation. Well, actually the code you posted is a good example where a return in a finally block is causing massive confusion. Even the, as of time of writing this, most upvoted answer, got it wrong. Your code will always execute the return null; as last command, even if there is an Exception.
But I can think of a situation where a return in a finally block actually makes sense. It appears to me that the goal of the author of your code was that the method never throws a Throwable, but returns null instead. This can actually be achieved if you modify the code like this:
public Result newStuff() {
Result res = null;
try {
res = someMethod();
log.info(res.toString());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
return res;
}
}
But note that this will not call printStackTrace() on Errors and Throwables which are not Exceptions.
The "Finally" block will execute regardless of whether the "Catch" fires or not. So the behaviour is different than if you just put "return null" in the Catch block.
There should be no return statement in the finally block,remove return.
The need of finally block is where when you have such a code that should always be executed like you want to close your input stream or you want to close any connection etc.Just googled about this you will easily find the example for this.
In your case you are writing a method where you are returning something in try block and at the end you are writing finally block where you are returning null.I don't see any use of finally block here.
Finally block is used if you want to execute some statements even if code in try block or catch block generates an exception or not. But as you are using return in try block then there is no significance of putting a return in finally block. You can return directly from catch block and can remove finally block.
First understand why we need this three blocks in simple words for beginners.
1)try block: If you have doubt that your code will lead to an exception then put in try block
2)catch block: If exception arises then a piece of code you need to perform should be written in this block
3)finally block: If you want your piece of code to be executed no matters if exception arises or not then we go for finally block. Mainly this block is use for releasing resources.
For example:
try{
Connection conn=//something;
//some code for database operations
}catch(SQLException e){
e.printStackTrace()
}finally{
conn=null;
}
No matter what is result, you have to make connection as null because it is heavy object which if referenced will create load on database as only few connection objects are available.
Hence best way to keep them in finally block.
In your case, return null in finally block is bad approach as it will always return null although exception arises or not.
What happens to the return A code in my catch block?
public class TryCatchFinallyTest {
#Test
public void test_FinallyInvocation()
{
String returnString = this.returnString();
assertEquals("B", returnString);
}
String returnString()
{
try
{
throw new RuntimeException("");
}
catch (RuntimeException bogus)
{
System.out.println("A");
return "A";
}
finally
{
System.out.println("B");
return "B";
}
}
}
The finally get's executed right before any return's / exits from the method. Therefore, when you do
return "A";
it executes like so:
System.out.println("B");//Finally block
return "B";//Finally block
return "A";//Return from exception catch
And thus the "B" is returned, not the "A"
Maybe return "A"; is optimized away by the compiler, maybe not and "A" is just dynamically replaced. In fact it doesn't matter as you should not have this code.
This is one of the classical examples of problems with using finally for control flows : you lose some instructions and another coder might not see the "intent" (in fact it can only be a bug or a mischief).
You may have noted that javac issues a warning "finally block does not complete normally".
Don't return in a finally clause
the finally block will always be executed, while the catch block is only executed if there's an exception caught.
Finally
You can attach a finally-clause to a try-catch block. The code inside the finally clause will always be executed, even if an exception is thrown from within the try or catch block. If your code has a return statement inside the try or catch block, the code inside the finally-block will get executed before returning from the method.
References http://tutorials.jenkov.com/java-exception-handling/basic-try-catch-finally.html
Before return "A" , finally block would be called which will return "B" and your return "A" would be skipped and would never be executed. Its because finally block is always executed before return statement of the method, and if you are returning something from finally block then the return statement of your try/catch would always skipped.
Note : Returning from finally block is not a good practice for a Java programmer. JAVA Compiler also show you the warning as "finally block does not complete normally" if you are returning something from finally block.
i was asked a question in interview what happens if we put finally block between try and catch block i answered in that case compiler will think that there is no catch block and it will directly execute finally block.
Then he asked why is it not possible to put code between try and catch block?
Can you please help me...
Okay, first thing first - the compiler doesn't execute the code, it just compiles it, allowing it to be run by the JVM.
Empirically speaking, that wouldn't make too much sense, since if you have some code that you would want to put outside the try block but before the catch block, the code could just as well be placed in the try block. The thing is, it would just behave as it were in the try block anyway if you think about it.
Let's assume this is valid Java (this doesn't compile):
try {
throw new Exception();
}
System.out.println("Sup!");
catch(Exception e) { }
When the exception gets thrown, that line that prints out Sup! will still get skipped as the JVM is searching to jump to the appropriate exception handler to treat Exception. So, in a way, the code behaves just as it would if it were in the try {} block itself, which is why it wouldn't really matter where it is, and the Java specifies that this (now proven useless) construct is illegal.
Now what if that code after the try were to throw another exception itself? If it were valid code, it would behave just like a nested try...catch block in the original try block. Of course that once things start getting complicated, the approach where there is no clear connection between a try and a catch block could get fuzzy, and the JVM would end up not knowing which catch/finally belongs to which try block (especially since the handler doesn't have to be in the same function, or even in the same package!).
Well, the flippant answer is that the language spec forbids it.
But let's step back a bit and think about it a different way - what if you could do this?
try {
foo();
}
bar();
catch (Exception e) {
baz();
}
What could the semantics of this be? If we catch an exception in foo(), is baz() called? What about bar()? If bar() throws, do we catch the exception in that case?
If exceptions in bar() are not caught, and exception in foo() prevent bar() from running, then the construct is equivalent to:
try {
foo();
} catch (Exception e) {
baz();
}
bar();
If exceptions in bar() are caught, and exception in foo() prevent bar() from running, then the construct is equivalent to:
try {
foo();
bar();
} catch (Exception e) {
baz();
}
If exceptions in bar() are not caught, and exception in foo() do not prevent bar() from running (bar() is always executed), then the construct is equivalent to:
try {
foo();
} catch (Exception e) {
baz();
} finally {
bar();
}
As you can see, any reasonable semantics for this between-try-catch construct are already expressible without the need for a new - and rather confusing - construct. It's hard to devise a meaning for this construct that is not already redundant.
As an aside, one potential reason we can't do:
try {
foo();
} finally {
bar();
} catch (Exception e) {
baz();
}
could be that it does not reflect actual execution order - catch blocks run before the finally block. This allows catch blocks to make use of resources that the finally block might release later (for example, to request additional diagnostic information from a RPC object or something). Could be made to work the other way as well? Sure. Is it worth it? Probably not.
Well it would mean something like this :
try
{
somCode();
}
someMoreCode();
catch
{
}
What should this mean ?
This is not possible because it has no semantic, and therefore it has been decided to be syntaxically incorrect by language designers!
If you have a try you must have either catch or finally, as defined in the java language specification, 14.20 "The try Statement`
try and catch like .. if and else ..
so there is no need to add code between try and catch block