Non throwable code inside of a try/catch performance java - java

Will there be any negative performance implications on the following code due to methods that do not throw exceptions being inside of a try block?
String user;
try {
user = SomeHelper.getUserName(); //Does not throw anything explicitly
if (SomeHelper.isSomething(user)) { //Does not throw anything explicitly
user.doSomeSafeThing(this); //Does not throw anything explicitly
}
else {
user.doOtherSafeThing(this); //Does not throw anything explicitly
}
SomeOtherHelper.methodThatCanBlow(User.getCredentials(context)); //This will throw exception
} catch (Exception e) {
e.printStackTrace();
}
I believe that the compiler will not refactor any of this code due to the fact that any of those methods could potentially throw a NullPointerException, or another RuntimeException and actually be caught in the catch block.
So I beg to ask the question, would the following code be more efficient?
String user;
user = SomeHelper.getUserName(); //Does not throw anything explicitly
if (SomeHelper.isSomething(user)) { //Does not throw anything explicitly
user.doSomeSafeThing(this); //Does not throw anything explicitly
}
else {
user.doOtherSafeThing(this); //Does not throw anything explicitly
}
try {
SomeOtherHelper.methodThatCanBlow(User.getCredentials(context)); //This will throw exception
} catch (Exception e) {
e.printStackTrace();
}

Will there be any negative performance implications on the following code due to methods that do not throw exceptions being inside of a try block?
No, it won't have any performance implications, but:
I would generally put minimal code in a try block anyway
I would try to avoid catching Exception, instead catching specific exceptions
Just printing a stack trace is very rarely the right way of "handling" and exception that you catch. Usually you want to abort the whole operation, whatever that consists of

Related

why is the Catch exception e printing instead of doing what is in Try

I am confused why it is going to catch and print the error occurred message when I run my code since it runs and just prints the message I can't tell what the error could be
Note: this is my very first time using try and catch my professor told us to use it but haven't really learned how it works fully yet so I'm not sure if the problem is with that or if it's just with my code
public static void main (String [] args) {
try {
File file = new File("in.txt");
Scanner scanFile = new Scanner(file);
...
} catch(Exception e) {
System.out.println("Error");
}
}
Do not catch an exception unless you know what to do. It is common that you don't - most exceptions aren't 'recoverable'.
So, what do you do instead?
Simplest plan: Just tack throws Exception on your main method. public static void main(String[] args) methods should by default be declared to throws Exception, you need a pretty good reason if you want to deviate from this.
Outside of the main method, think about your method. Is the fact that it throws an exception an implementation detail (a detail that someone just reading about what the method is for would be a bit surprised by, or which could change tomorrow if you decide to rewrite the code to do the same thing but in a different way)? In that case, do not add that exception to the throws clause of your method. But if it is, just add it. Example: Any method whose very name suggests that file I/O is involved (e.g. a method called readFile), should definitely be declared to throws IOException. It'd be weird for that method not to throws that.
Occasionally you can't do that, for example because you're overriding or implementing a method from an interface or superclass that doesn't let you do this. Or, it's an implementation detail (as per 2). The usual solution then is to just catch it and rethrow it, wrapped into something else. Simplest:
} catch (IOException e) {
throw new RuntimeException("uncaught", e);
}
Note that the above is just the best default, but it's still pretty ugly. RuntimeException says very little and is not really catchable (it's too broad), but if you don't really understand what the exception means and don't want to worry about it, the above is the correct fire-and-forget. If you're using an IDE, it probably defaults to e.printStackTrace() which is really bad, fix that template immediately (print half the details, toss the rest in the garbage, then just keep on going? That's.. nuts).
Of course, if you know exactly why that exception is thrown and you know what to do about it, then.. just do that. Example of this last thing:
public int askForInt(String prompt) {
while (true) {
System.out.println(prompt + ": ");
try {
return scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("-- Please enter an integral number");
}
}
}
The above code will catch the problem of the user not entering an integer and knows what to do: Re-start the loop and ask them again, until they do it right.
Just add throws Exception to your main method declaration, and toss the try/catch stuff out.
There are a couple of problems with your current code:
catch (Exception e) {
System.out.println("Error occured...");
}
Firstly, you are not printing any information about the exception that you caught. The following would be better:
catch (Exception e) {
System.out.println(e.getMessage()); // prints just the message
}
catch (Exception e) {
System.out.println(e); // prints the exception class and message
}
catch (Exception e) {
e.getStackTrace(System.out); // prints the exception stacktrace
}
Secondly, for a production quality you probably should be logging the exceptions rather than just writing diagnostics to standard output.
Finally, it is usually a bad idea to catch Exception. It is usually better to catch the exceptions that you are expecting, and allow all others to propagate.
You could also declare the main method as throws Exception and don't bother to catch it. By default, JVM will automatically produce a stacktrace for any uncaught exceptions in main. However, that is a lazy solution. And it has the disadvantage that the compiler won't tell you about checked exceptions that you haven't handled. (That is a bad thing, depending on your POV.)
now null printed out.
This is why the 2nd and 3rd alternatives are better. There are some exceptions that are created with null messages. (My guess is that it is a NullPointerException. You will need a stacktrace to work out what caused that.)
Catching Exception e is often overly broad. Java has many built-in exceptions, and a generic Exception will catch all of them. Alternatively, consider using multiple catch blocks to dictate how your program should handle the individual exceptions you expect to encounter.
catch (ArithmeticException e) {
// How your program should handle an ArithmeticException
} catch (NullPointerException e) {
// How your program should handle a NullPointerException
}

How to handle exceptions that you didn't expect even thought it is declared on the documentation?

When there are methods that throw exceptions and you know these exceptions will not be thrown, what should you do?
Many times I see people just logging the exception, but I wonder if there is a build in exception in java that means something like: "This exception should not have been thrown".
For example, imagine I have a code that calls StaticClass.method(someObject) and this method throws a SpecificException when someObject is not valid. What should you do in the catch block?
try {
StaticClass.method(someobject);
} catch (SpecificException e) {
// what should I do here?
}
If when calling the method you know for sure that it will not throw an exception because of previous checks you should throw a RuntimeException wrapping the SpecificException.
try {
StaticClass.method(someobject);
} catch (SpecificException e) {
//This is unexpected and should never happen.
throw new RuntimeException("Error occured", e);
}
Some methods already throw a RuntimeException when they fail to perform their purpose.
//Here we know for sure that parseInt(..) will not throw an exception so it
//is safe to not catch the RuntimeException.
String s = "1";
int i = Integer.parseInt(s);
//Here instead parseInt(..) will throw a IllegalArgumentException which is a
//RuntimeException because h is not a number. This is something that should
//be fixed in code.
s = "h";
i = Integer.parseInt(s);
RuntimeExceptions don't require a try/catch block and the compiler will not be mad at you for not catch them. Usually they are thrown where something in your app code is wrong and should be fixed. Anyway there are cases where catching a RuntimeException is useful.

Exception hierarchy/try-multi-catch

try {
throw new FileNotFoundException();
} catch (IOException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
Can someone tell me why the second catch block is not considered as unreachable code by the compiler? But in the following case:
try {
throw new FileNotFoundException();
} catch (Exception e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
The second catch block is considered unreachable?
After all, FileNotFoundException comes under IOException, just as it comes under Exception.
Edit Please clarify:
The compiler will know an exception is thrown by a method based on the method's throws clause. But it may not necessarily know the specific type of exception (under that class of exception). So if a method throws exception 'A', compiler won't know if the actual exception is 'A' or a subtype of 'A' because this is only determined at runtime. The compiler however will know that an exception of type 'X' is never thrown, so giving a catch block for X is erroneous. Is this right?
The compiler cannot assume that the only possible exception thrown from your try block will be a FileNotFoundException. That's why it doesn't consider the 2nd catch block to be unreachable in your first code sample.
What if, for some unknown reason, a RuntimeException gets thrown while creating the FileNotFoundException instance (entirely possible)? What then?
In your first code sample, that unexpected runtime exception would get caught by the 2nd catch block, while the 1st block would take care of the FileNotFoundException if it gets thrown.
However, in your 2nd code sample, any and all exceptions would get caught by the 1st catch block, making the 2nd block unreachable.
EDIT:
To better understand why the catch(Exception e) block in your first code is not considered unreachable by the compiler, try the following code, and notice how the the 2nd catch is definitely reachable:
public class CustomIOException extends IOException {
public CustomIOException(boolean fail) {
if (fail) {
throw new RuntimeException("the compiler will never know about me");
}
}
}
public static void main(String[] args) {
try {
throw new CustomIOException(true);
} catch(IOException e) {
System.out.println("Caught some IO exception: " + e.getMessage());
} catch(Exception e) {
System.out.println("Caught other exception: " + e.getMessage());
}
}
Output:
Caught other exception: the compiler will never know about me
TL;DR
The compiler considers that FileNotFoundException() may not be the only Exception thrown.
Explaination
JLS§11.2.3 Exception Checking
A Java compiler is encouraged to issue a warning if a catch clause can
catch (§11.2) checked exception class E1 and the try block
corresponding to the catch clause can throw checked exception class
E2, a subclass of E1, and a preceding catch clause of the immediately
enclosing try statement can catch checked exception class E3 where E2
<: E3 <: E1.
That means that if the compiler considers that the only exception possibly thrown by your catch block is a FileNotFoundException(), it will warn you about your second catch block. Which is not the case here.
However, the following code
try{
throw new FileNotFoundException();
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){ // The compiler warns that all the Exceptions possibly
// catched by IOException are already catched even though
// an IOException is not necessarily a FNFException
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
This happens because the compiler evaluates the try block to determine which exceptions has the possibility to be thrown.
As the compiler does not warn us on Èxception e, it considers that other exceptions may be thrown (e.g RunTimeException). Since it is not the compiler's work to handle those RunTimeExceptions, it lets it slip.
Rest of the answer is intersting to read to understand the mechanism behind exception-catching.
Schema
As you may see, Exception is high in the hierarchy so it has to be declared last after IOException that is lower in the hierarchy.
Example
Imagine having an IOException thrown. As it is inherited from Exception, we can say IOException IS-A Exception and so, it will always be catched within the Exception block and the IOException block will be unreachable.
Real Life Example
Let's say, you're at a store and have to choose pants. The seller tells you that you have to try the pants from the largest ones to the smallest ones and if you find one that you can wear (even if it is not your size) you must take it.
You'll find yourself buying pants too large for your size and you'll not have the chance to find the pants that fits you.
You go to another store : there, you have the exact opposite happening. You can choose your pants from smallest to largest and if you find one you can wear, you must take it.
You'll find yourself buying pants at your exact size.
That's a little analogy, a bit odd but it speaks for itself.
Since Java 7 : multi-catch
Since Java 7, you have the option to include all the types of Exceptions possibly thrown by your try block inside one and only catch block.
WARNING : You also have to respect the hierarchy, but this time, from left to right.
In your case, it would be
try{
//doStuff
}catch(IOException | Exception e){
e.printStackTrace();
}
The following example, which is valid in Java SE 7 and later,
eliminates the duplicated code:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
The catch clause specifies the types of exceptions that the block can
handle, and each exception type is separated with a vertical bar (|).
First case:
catch (IOException e) { // A specific Exception
e.printStackTrace();
}
catch (Exception e) { // If there's any other exception, move here
e.printStackTrace();
}
As you can see, first IOException is catched. This means we are aiming at just one specific exception. Then in second catch, we aim for any other Exceptions other than IOException. Hence its logical.
In second:
catch (Exception e) { // Move here no matter whatever exception
e.printStackTrace();
}
catch (IOException e) { // The block above already handles *Every exception, hence this won't be reached.
e.printStackTrace();
}
We catched any exception (whether its IOException or some other Exception), right in the first block. Hence second block will not be reached because everything is already included in first block.
In other words, in first case, we aim at some specific exception, than at any other exceptions. While in second case, we first aim at all/any Exception, than at a specific exception. And since we already dealt will all exceptions, having a specific exception later won't make any logical sense.

How do i handle the exception in an own function that Java compiles again?

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

why is it not possible to insert code between try and catch 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

Categories