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
}
Related
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);
}
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?
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.
This program is about auto complete. When I type something to the textfield, a list of suggestions will appear.
I make the method onWordUpdated() for a list of suggestions from the DB when I type something to the textfield.
Now, the problem is I have this error:
exception java.sql.SQLException is never thrown in body of corresponding try statement
I made a comment in the code so that you will know which line.
Could someone help me how to fix this?
thanks..
I have this code:
public void onWordUpdated(final String toComplete)
{
new Thread(new Runnable()
{
public void run()
{
try
{
final List<Suggestion> suggestions = suggestor.getSuggestions(toComplete);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
suggestionWidgetModel.clear();
for (Suggestion suggestion : suggestions)
suggestionWidgetModel.addElement(suggestion.getCaption());
if (!suggestions.isEmpty())
suggestionWidget.setSelectedIndex(0);
}
catch (SQLException e) // This line is my problem, Could someone help me how to fix this? Thanks..
{
e.printStackTrace();
}
}
});
}
catch (SQLException e1)
{
onSqlError(e1);
}
}
}, "onWordUpdated").start();
}
The compiler is simply telling you that you don't need to catch that exception at that point.
SQLException is a checked exception, which means that your code should only see it if you either explicitly throw it, or you call a method that declares it in its throws clause. Neither of these is true for the code in that particular try/catch block.
You should be able to just get rid of the inner try/catch block and probably the outer one too.
IIRC, it is theoretically possible to see checked exceptions that haven't been declared, but this unlikely to arise unless you take special steps to make it happen.
Java has two types of exceptions: unchecked (those that inherit from RuntimeException or Error) and checked (all others that inherit from Exception).
A checked exception has the following properties:
If a block of code throws one, it must be caught in a catch block or the method must declare that it may throw that type of Exception.
If some code calls a method that throws SomeException, that code must also be in a try-catch or its method must also specify throws SomeException.
Because of the first two checks, the compiler can detect whether a checked exception can actually be thrown in a certain block of code. As a result, this leads to a third property:
If the catch clause of a try-catch block declares an Exception type that cannot occur in the try block, then a compile error is generated. The compiler does this primarily to tell you that you've made an error: you're dealing with an exception that will never be thrown.
SQLException is a checked exception so it is subject to those rules. None of the lines of code (or the methods they call) in the try block below can ever throw a SQLException so the compiler tells you via a compile error.
try {
suggestionWidgetModel.clear();
for (Suggestion suggestion : suggestions)
suggestionWidgetModel.addElement(suggestion.getCaption());
if (!suggestions.isEmpty())
suggestionWidget.setSelectedIndex(0);
}
catch (SQLException e) // This line is my problem, Could someone help me how to fix this? Thanks..
{
e.printStackTrace();
}
In a Java program I am currently getting "Unhandled Exception" at a certain point in the program and I can't seem to determine the location where this is being generated.
Its also difficult to debug the code as the program contains streams that handle wireless data bytes sent and received. I can't seem to simulate that with a debugger.
What strategy should I adopt to locate the Exception?
Implement the Thread.UncaughtExceptionHandler interface and use setDefaultUncaughtExceptionHandler() to set it.
Sample program as courtesy. If you use multiple threads you also could just set the handler on threads you suspect to be the culprits.
public class Test {
public static void main(String args[]) {
new Test();
}
public Test() {
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
// or if a default handler is set you can also use setUncaughtExceptionHandler
// check the javadocs for the specifics
throw new RuntimeException ("You can't get me or can you?");
}
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.err.println ("Uncaught exception by " + t + " caught:");
e.printStackTrace();
}
}
}
You could put a try-catch(Exception ex) block around sections of code and move it around/tighten the block and have it log the exception being thrown. As long as there isn't too much code you should be able to track it down in a few runs.
But as I run the program the device
shows "Unhandled Exception" and asks
me whether to close the app.
First you need to find the place in the code that is generating this message. It sounds like the app has a GUI or whatever, so it is possible a Dialog of some kind.
Next, find the place in the code that is causing the message/dialog to be created. It is likely to be either
a try / catch block that catches Exception or Throwable, or
an UncaughtExceptionHandler.
In either case, the next thing is to add some code to cause the app to output a stacktrace for the uncaught exception. Assuming that ex holds a reference to the exception object:
ex.printStackTrace();
will write a stack trace to the standard error stream; e.g. the "console". (There are more heavy-weight solutions if you cannot find where "console" output goes to.)
Sounds like you've got an unchecked RuntimeException happening somewhere. You could easily try it in your main() method with try { } catch(Throwable t) { t.printStackTrace(); }
Or if you remotely debug it with an IDE like Eclipse, you can set it up to trigger the debugger on a Java exception breakpoint with "Suspend on uncaught exceptions". Some docs here.
If you don't have a stacktrace, you can't do much.
If it is actually caused at the other side and you received this as a message, then you should ask the other side for a stacktrace or similar information.
Edit: you should of course ensure that your own code isn't swallowing exceptions like as:
} catch (Exception e) {
// Do nothing.
}
or
} catch (Exception e) {
System.out.println("Error");
}
or
} catch (Exception e) {
System.out.println(e.toString());
}
To get the most information out of exceptions, you should do at least:
} catch (Exception e) {
e.printStackTrace();
}
or just
} catch (Exception e) {
throw e;
}
Hope this helps.