Why am I not forced to catch Exception here? - java

Ran across something that's got me puzzled. Why am I not forced to declare "throws Exception" in the method signature here?
public static void main(String[] args) {
try
{
System.out.println("foo");
// throw new Exception();
}
catch ( Exception e )
{
throw e;
}
}
Now, if I enable the commented out line, it does force me to declare it which is what I'd expect. I suppose this qualifies more in the Java puzzle category and it's really bugging me that I can't figure it out :)

The compiler is doing data flow analysis and realizing that the only exceptions that can be thrown in that segment are unchecked. So, what you re-throw is an unchecked exception which does not require declaration.

Related

How to make sure that exceptions do not lose its stack trace information in java?

Recently, I met some exception problem in java, which reminded me of the typical idiom recommended by Bruce Eckel:
Converting checked to unchecked exceptions
The real problem is when you are writing an ordinary method body, and you call another method and realize, "I have no idea what to do with this exception here, but I don’t want to swallow it or print some banal message." With chained exceptions, a new and simple solution prevents itself. You simply "wrap" a checked exception inside a RuntimeException by passing it to the RuntimeException constructor, like this:
try {
// ... to do something useful
} catch (IDontKnowWhatToDoWithThisCheckedException e) {
throw new RuntimeException(e);
}
This seems to be an ideal solution if you want to "turn off the checked exception—you don’t swallow it, and you don’t have to put it in your method’s exception specification, but because of exception chaining you don’t lose any information from the original exception.
This technique provides the option to ignore the exception and let it bubble up the call stack without being required to write try-catch clauses and/or exception specifications.
However, I found it didn't work in some cases. as seen here:
package exceptions;
// How an exception can be lost
class VeryImportantException extends Exception {
#Override
public String toString() {
return "A very important exception";
}
}
class HoHumException extends Exception {
#Override
public String toString() {
return "A trivial exception";
}
}
public class LostMessage {
void f() throws VeryImportantException {
throw new VeryImportantException();
}
void dispose() throws HoHumException {
throw new HoHumException();
}
public static void main(String[] args) {
try {
LostMessage lm = new LostMessage();
try {
lm.f();
} catch (VeryImportantException e) {
throw new RuntimeException(e);
} finally {
lm.dispose();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}/* Output:
Exception in thread "main" java.lang.RuntimeException: A trivial exception
at exceptions.LostMessage.main(LostMessage.java:36)
Caused by: A trivial exception
at exceptions.LostMessage.dispose(LostMessage.java:23)
at exceptions.LostMessage.main(LostMessage.java:33)
*///:~
As the output demonstrated, the second exception completely obliterates the first one. There is no record of the first exception in the exception stack trace, which can greatly complicate debugging in real systems. usually, it’s the first exception that you want to see in order to diagnose the problem.
Joshua Bloch recommends the try-with-resource way that a resource must implement the AutoCloseable interface, which process is somewhat complex.
So, my question is this: is there any way I can use to make sure that exception will not lose its stack trace information by Bruce Eckel's approach?
You might want to consider using try-with-resource instead of a finally block. It tends to handle this situation more like it sounds you would want the situation handled. See this article for more details.
Alternatively, you could simply eat the exception (as Andy Thomas's answer shows), or (if you want to know about both exceptions that were thrown) you could combine the exceptions into a single kind of Aggregate Exception.
The problem isn't that you're wrapping the exception. The problem is that you're replacing it with a subsequent, unrelated exception thrown from the finally block.
One easy way to avoid this is to not throw an exception from the finally block.
For example:
try {
LostMessage lm = new LostMessage();
try {
lm.f();
} catch (VeryImportantException e) {
throw new RuntimeException(e);
} finally {
try {
lm.dispose();
} catch ( HoHumException e ) {
// No-op or logging
//
// If we're exiting this try-finally because an exception
// was thrown, then don't allow this new exception to replace it.
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}

What is the meaning of this statement from a blog saying a function has to declare Throwable at method signature to catch it?

I am trying to understand exception handling in Java and i keep running into variations of the below mentioned confusing statement in several articles -
There are several reasons why catching instance of java.lang.Throwable is bad idea, because in order to catch them you have to declare at your method signature e.g. public void doSomething() throws Throwable.
This is from http://javarevisited.blogspot.com/2014/02/why-catching-throwable-or-error-is-bad.html#ixzz4hQPkFktf
However, this code compiles -
class CatchThrowable
{
void function()
{
try
{
throw new Throwable();
}
catch (Throwable t)
{
}
}
public static void main(String[] args)
{
try
{
}
catch (Throwable t)
{
}
}
}
Both main and function are able to catch Throwable without declaring that they throw it. My understanding is that the throws keyword is used to declare the checked exceptions which a function throws, not those which it catches. Please clarify the quoted statement.
The statement:
order to catch them you have to declare at your method signature e.g. public void doSomething() throws Throwable.
is basically wrong.
You just have to understand the following. There is a exception Hierarchy
A method can throw all types of exception, it just depends on your needs which one you catch and which one not.
It is also not a good idea to catch Error (which includes that you should also not catch Throwable) because there are some severe JMV-VirtualMachineError's like OutOfMemoryError which you usually not should catch.
But this has nothing to do which the fact, what a method declares in its throws part.

Fatal exception handling in Java

I am creating a basic math parser with Java and doing this is revealing my shallow understanding of Java exception handling.
when I have this input:
String mathExpression = "(3+5";
and I subsequently call:
throw new MissingRightParenException();
the IDE forces me to surround with a try/catch like so:
try {
throw new MissingRightParenException();
} catch (MissingRightParenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
however, in order to force this to be a fatal exception, it looks like I have to add my own code to call System.exit(), like so:
try {
throw new MissingRightParenException();
} catch (MissingRightParenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(0);
}
I am not sure I understand the syntax behind all of this, especially why I have to use a try/catch block around throwing an exception.
what is the rhyme and reason behind this?
Instead of throwing the exception, I could do this instead:
new MissingRightParenException();
instead of calling
throw new MissingRightParenException();
so I guess my question is - if this is a fatal exception, what is the best way to make it truly fatal while giving the user the best feedback?
If you want to have a checked exception that you have to catch - but not right away - then you can define throws MissingRightParenException in the signature of your methods.
class MissingRightParenException extends CalculationException {
...
}
class CalculationException extends Exception {
...
}
class MyClass {
int myMathRelatedMethod(String calculation) throws CalculationException {
...
if (somethingWrong) {
throw new MissingRightParenException("Missing right paren for left paren at location: " + location);
}
...
}
public static void main(String ... args) {
...
try {
myMathRelatedMethod(args[0]);
} catch (CalculationException e) {
// stack trace not needed maybe
System.err.println(e.getMessage());
}
...
}
}
You can also define it as the cause of a RuntimeException but that doesn't seem a good match for your current problem.
try {
...
throw new MissingRightParenException();
...
} catch (MissingRightParenException e) {
// IllegalStateException extends (IS_A) RuntimeException
throw new IllegalStateException("This should never happen", e);
}
If your MissingRightParenException class extends RuntimeException then you don't have to catch it. The message will fall through all methods where it (or it's parent classes such as Throwable, Exception and RuntimeException) is not explicitly caught. You should however not use RuntimeExceptions for input related errors.
Usually the user will get the stack trace or at least the error message, although that depends of course or the error handling further down the line. Note that even main does not have to handle exceptions. You can just specify throws Exception for the main method to let the console receive the stack traces.
So in the end: use throws in the signature of your methods instead of catching exceptions before you want to handle them.
Assuming that your exception is currently a subclass of Exception, which is a Checked Exception, you need to handle in a try catch. If you can make your exception a RunTimeException, you no longer need to do the try-catch stuffs.
what is the best way to make it truly fatal while giving the user the
best feedback?
Personally, I don't think a missing parenthesis should be a Fatal exception. The user should have the possibility to re-try.
However, if you really want to know, It is not possible with java to create a custom fatal exception as fatal exception means something went wrong on the system/jvm, not on the program itself. Still, you should change System.exit(0) to System.exit(1) or anything not equal to 0 as a program exiting with 0 as error code mean everything went right which is not the definition of an exception.
I am not sure I understand the syntax behind all of this
Basically what you do here is throw an exception so you have two choices, either catch it or re-throw it but anyway it will have to be caught somewhere. Then in the catch you simply end the program returning an error code meaning that something failed System.exit(1)
See this Difference in System. exit(0) , System.exit(-1), System.exit(1 ) in Java for a better understanding of error code.
If MissingRightParenException is a checked exception (that seems to be the case, otherwise your IDE wouldn't be "nagging") then either you have to wrap it inside a try ... catch block or declare it via a throws clause in the method definition. The latter allows you to "bubble up" the exception and catch in the caller of your method throwing the MissingRightParenException exception.
Did you think about a throws clause?

Java : Unknown error in exception handling

i have a weird question. i had a quiz in my class today. One portion of the quiz was to find and correct errors in a short piece of code. one of the questions was like this
class Example {
public static void main(String[] args) {
try {
System.out.println("xyz");
} catch (Exception e) {
System.out.println("Exception caught");
} finally {
System.out.println("abc");
}
}
}
I thought there was no error in the program but my professor insisted that there was. Can anyone guess what the error is?
The "error" may be that you don't need to handle any exception here: System.out.println does not specify any checked exception. It could simply be:
public static void main(String[] args) {
System.out.println("xyz");
}
Since the Exception class covers both checked and unchecked exceptions, then if you add a catch block here, in this case you would be handling only unchecked exceptions, which you should not normally handle.
There is no Error in the Above Program , but also there is no need to put a try{} catch{} ....since you don't use any code that can throw an Exception , for example a risky method like Thread.sleep();
So maybe that’s what your professor meant .
Well, I see nothing that would keep this from compiling, but I do see some problems. To begin with, there are comments indicating the presence of code which is not there. Comments out of sync with code is always a problem.
[EDIT: indentation errors have been edited away] And you're catching Exception e, which you really oughtn't to do. You should always catch a specific exception that you expect to encounter, and handle it specifically. Since there's no exception that System.out.println can throw, this would make the whole Exception handling block a problem.
The following code snippet would throw a compilation error if used with IOException, since System.out.println would never throw an IOException but could throw Exception or Throwable which is its super class.
try {
System.out.println("xyz");
} catch (IOException e) {
//simple display error statement here
} finally {
//simple print statement here
}

Is it possible to ignore an exception?

In Java, is it possible to make a method that has a throws statement to be not checked.
For example:
public class TestClass {
public static void throwAnException() throws Exception {
throw new Exception();
}
public static void makeNullPointer() {
Object o = null;
o.equals(0);//NullPointerException
}
public static void exceptionTest() {
makeNullPointer(); //The compiler allows me not to check this
throwAnException(); //I'm forced to handle the exception, but I don't want to
}
}
You can try and do nothing about it:
public static void exceptionTest() {
makeNullPointer(); //The compiler allows me not to check this
try {
throwAnException(); //I'm forced to handle the exception, but I don't want to
} catch (Exception e) { /* do nothing */ }
}
Bear in mind, in real life this is extemely ill-advised. That can hide an error and keep you searching for dogs a whole week while the problem was really a cat(ch). (Come on, put at least a System.err.println() there - Logging is the best practice here, as suggested by #BaileyS.)
Unchecked exceptions in Java extend the RuntimeException class. Throwing them will not demand a catch from their clients:
// notice there's no "throws RuntimeException" at the signature of this method
public static void someMethodThatThrowsRuntimeException() /* no need for throws here */ {
throw new RuntimeException();
}
Classes that extend RuntimeException won't require a throws declaration as well.
And a word from Oracle about it:
Here's the bottom line guideline: If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.
There are 3 things you can do :
Throw a RuntimeException (or something extending a RuntimeException, like NullPointerException, IllegalArgumentException,...), you don't have to catch these as they are unchecked exceptions.
Catch the exception and do nothing (not recommended) :
public static void exceptionTest() {
makeNullPointer(); //The compiler allows me not to check this
try {
throwAnException(); //I'm forced to handle the exception, but I don't want to
} catch (Exception e) {
// Do nothing
}
}
Change exceptionTest () declaration to say that it throws an Exception, and let the method calling it catch the Exception and do what is appropriate :
public static void exceptionTest() throws Exception {
makeNullPointer(); //The compiler allows me not to check this
throwAnException(); //I'm no more forced to handle the exception
}
In Java there is two kinds of Exceptions, Checked Exceptions and Unchecked Exceptions.
Exception is a checked exception, must caught or thrown.
NullPointerException is a RuntimeException, (the compiler doesn’t forces them to be declared in the throws claus) you can ignore it, ,but it still may occur in the Runtime, and your application will crash.
From Exception documentation:
The class Exception and any subclasses that are not also subclasses of
RuntimeException are checked exceptions. Checked exceptions need to be
declared in a method or constructor's throws clause if they can be
thrown by the execution of the method or constructor and propagate
outside the method or constructor boundary.
From the RuntimeException documentation:
RuntimeException is the superclass of those exceptions that can be
thrown during the normal operation of the Java Virtual Machine.
RuntimeException and its subclasses are unchecked exceptions.
Unchecked exceptions do not need to be declared in a method or
constructor's throws clause if they can be thrown by the execution of
the method or constructor and propagate outside the method or
constructor boundary.
No, it raises a compiler error. Being a checked exception, you must either catch it or propagate it by declaring your method as potentially throwing it.
Check this and this.
Throw a RuntimeException or an exception which is derived from RuntimeException. Then the compiler will not force you to catch it.
The other answers are right, in that they correctly tell you what you should do, but it is actually possible to throw a undeclared checked exception. There are a few ways this can be done; the simplest is:
public void methodThatSecretlyThrowsAnException() {
Thread.currentThread().stop(new Exception());
}
or if your goal is to wrap an existing method that does declare its exception
public void methodThatSecretlyThrowsAnException() {
try {
methodThatAdmitsItThrowsAnException();
} catch(final Exception e) {
Thread.currentThread().stop(e);
}
}
(Needless to say, you should never do this.)
Just catch an exception and dont do any thing with it, leave it as it is and catch the generic exception in case you are not aware of the specific exception
try{
//Your logic goes here
}
catch(Exception e)//Exception is generic
{
//do nothing
}
AS I know, it's impossible in the case. Only unchecked exception, compiler can skip to check. such as RuntimeException.
You can use a loophole in the Java Compiler. Add the following code:
public RuntimeException hideThrow(Throwable e) {
if (e == null)
throw new NullPointerException("e");
this.<RuntimeException>hideThrow0(e);
return null;
}
#SuppressWarnings("unchecked")
private <GenericThrowable extends Throwable> void hideThrow0(Throwable e) throws GenericThrowable {
throw (GenericThrowable) e;
}
You can catch the exception, then invoke hideThrow with the exception to throw it without the compiler noticing. This works because of type erasure. At compile time, GenericThrowable represents RuntimeException because that is what we are passing. At run time, GenericThrowable represents Throwable because that is the basic type in the type parameter specification.
It is not advisable to avoid an exception with an empty catch block even though you are completely sure that is not going to fail under any circumstance. Sometimes, we are not aware of the human factor.
If you are sure that an exception is very unlikely to happen (if not impossible) you should create your own Exception and and wrap the unexpected exception in it.
For example:
private class UnlikelyException extends RuntimeException {
public UnlikelyException (Exception e){
super (e);
}
}
Then wrap your code with a try-catch block and throw your exception, which you don't have to catch
try {
// Your code
} catch (Exception e) {
throw new UnlikelyException(e);
}

Categories