Ok ... So I am learning about exceptions in java and i am currently at throw statements. I throw an exception of Exception class, and then re-throw it from the catch block again to handle it in the main function. But whenever i throw it as Exception class, i always get an Error in the catch block(where i re-throw it to be handled in main).But as soon as i change the thrown and caught Exceptions to some particular Exceptions like NullPointerException, it works!
Error Code:
class ThrowingExceptions {
static boolean enable3dRendering = false;
public static void main(String [] com) {
try {
renderWorld();
}
catch(Exception e) {
System.out.println("Rendering in 2d.");
}
}
static void renderWorld() {
try{
if(!enable3dRendering) {
System.out.println("3d rendering is disabled. Enable 3d mode to render.");
throw new Exception("3d mode Disabled.");
}
else {
System.out.println("The World is Empty!");
}
}
catch(Exception e) {
System.out.println("Please handle the error");
throw e; // It gives me an error here
}
}
}
Working Code:
class ThrowingExceptions {
static boolean enable3dRendering = false;
public static void main(String [] com) {
try {
renderWorld();
}
catch(NullPointerException e) {
System.out.println("Rendering in 2d.");
}
}
static void renderWorld() {
try{
if(!enable3dRendering) {
System.out.println("3d rendering is disabled. Enable 3d mode to render.");
throw new NullPointerException("3d mode Disabled.");
}
else {
System.out.println("The World is Empty!");
}
}
catch(NullPointerException e) {
System.out.println("Please handle the error");
throw e;
}
}
}
Why doesn't it work with Exception class and worked with its subclass??
Note :- The error i get in the error code is Unhandled exception type Exception
Runtime exceptions extend RuntimeException. They don’t have to be handled or declared.
They can be thrown by the programmer or by the JVM.
Checked exceptions have Exception in their hierarchy but not RuntimeException. They
must be handled or declared. They can be thrown by the programmer or by the JVM.
Errors extend the Error class. They are thrown by the JVM and should not be handled or
declared.
When method throws checked exception (1) you should handle or rethow it.
When method throws uncheked exception (2) you can handle or rethrow it, but it's not obligatory.
But whenever i throw it as Exception class, i always get an Error in
the catch block(where i re-throw it to be handled in main)
It means that your method is throwing checked exception which should be handled or rethrowed.
Handling:
public class Main {
public static void main(String[] args) {
try {
throw new Exception();
} catch (Exception e) {
try {
throw new Exception();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
Rethrowing:
public class Main {
public static void main(String[] args) throws Exception {
try {
throw new Exception();
} catch (Exception e) {
throw new Exception();
}
}
}
In your case:
// You declaring that the caller should handle exception
static void renderWorld() throws Exception {
try {
if(!enable3dRendering) {
System.out.println("3d rendering is disabled. Enable 3d mode to render.");
throw new Exception("3d mode Disabled.");
} else {
System.out.println("The World is Empty!");
}
} catch(Exception e) {
System.out.println("Please handle the error");
// You cannot just throw uncheked exception here
// You should handle it yourself or a caller should do it
throw e;
}
}
Changing
static void renderWorld() { ... }
to
static void renderWorld() throws Exception { ... }
should fix this. This is for the reason that runtime exception are unchecked exceptions.
Would recommend you to read about the Checked and Unchecked exception in details here - Java: checked vs unchecked exception explanation.
It's because they are several Exception classes which are inherited from the class Exception. Each can be throwed, catched but they divide into two groups:
Checked and unchecked exceptions:
An unchecked exception doesn't need to be handled and the
NullPointerException which you tried is from that group, so you don't need to care about it technically.
A checked exception need to be handled every time or it won't
compile, these exceptions are like IOException.
Since the base Exception Object can be checked and unchecked as well the compiler cares about that it should be handled everytime.
If you give it a try and change the NullPointerException to IOException it won't compile either cause it is a Checked Exception. So it was just random, that you exactly find one type of Exception which your code can be work without compile error.
For more info visit my blog post about it:
http://www.zoltanraffai.com/blog/?p=93
Related
I have the following piece of code, and I'm trying to understand how can I correctly handle exception in catch block so both exceptions (mainException and anotherException) are thrown so in case of anotherException we do not lose info from mainException.
Also code smells bad - is this kind of try-catch usage is some kind of anti-pattern? Is there a better/correct way to handle this kind of situations?
try {
-some code-
} catch (RuntimeException mainException) {
try {
-another code-
} catch (Exception anotherException) {
throw anotherException;
} finally {
throw mainException;
}
}
In Java 7, as part of the work on try-with-resources, the Throwable class was extended with support for suppressed exceptions, specifically intended for scenarios like this.
public static void main(String[] args) throws Exception {
try {
throw new RuntimeException("Foo");
} catch (RuntimeException mainException) {
try {
throw new Exception("Bar");
} catch (Exception anotherException) {
mainException.addSuppressed(anotherException);
}
throw mainException;
}
}
Output (stacktrace)
Exception in thread "main" java.lang.RuntimeException: Foo
at Test.main(Test.java:5)
Suppressed: java.lang.Exception: Bar
at Test.main(Test.java:8)
Error message:This exception is never thrown from the try statement body.
Here shows a java program:
class err1 extends Exception {}
class Obj1 {
Obj1() throws err1 {
throw new err1();
}
}
class Main {
public static void main(String[]argv) {
Class a[] = {Obj1.class};
try {
a[0].newInstance();
} catch(err1 e) { //Here meet my error
}
}
}
What shall I do to deal it?
Not to tell me to replace catch(err1 e) to catch(Exception e), for my Eclipse doesn't know a Exception can be thrown.
In addition,when I launch it,things as follows happened.
Exception in thread "main" java.lang.Error:Unresolved compilation problem:
Unreachable catch block for err1. This exception is never thrown from the try statement body
then I suddenly knew what I shall do...
The reflective method newInstance(), throws, amongst other things, InstantiationException. This will be thrown if an exception of any type is encountered in a constructor. You need to catch that one, and abstract your err1 using appropriate methods in the InstantiationException class.
newInstance() does not know about your specific exception per se, but rather it encapsulates it in the InstantiationException.
The Exception type is not known at compile time, since anything could be contained inside the Class array.
What you could do is check for the type in the catch block:
public class Example {
public static void main(String[] args) {
Class a[] = {Obj1.class};
try {
a[0].newInstance();
} catch (Exception e) {
if(e instanceof CustomException) {
System.out.println("CustomException");
}
}
}
}
class Obj1 {
Obj1() throws CustomException {
throw new CustomException();
}
}
class CustomException extends Exception {
}
Can't resist to mention: It is very helpful to others if you adhere to generally accepted coding/naming/formatting conventions.
I have a main class where I have something like
void FooBar(String s){
try {
parseString(s);
} catch (Exception e) {
e.printStackTrace();
System.err.println("Error: " + e.getMessage());
context.getCounter(Counters.ERROR).increment(1); // this increment doesnt increases
}
}
parseString is
void ParseString(String s){
if (matcher.matches()) {
} else {
//throw exception
try {
throw new Exception("bad formatted N-triples");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
But for some reason, the error is not propagated upwards. In my FooBar method the error counters are not incremented even if the function gets bad formatted data.
How do I propagate this exception upwards?
But for some reason, the error is not propagated upwards...
The reason it is not propagated upwards is that you caught it. Exceptions stop propagating when they are caught.
Either don't catch it in parseString, or rethrow it in the handler; e.g. e.printStackTrace(); throw e;
However, this is likely to get you into more problems, specifically because of the exception you are catching / throwing here. The problem is that Exception is the root of all checked exceptions:
Since it is a checked exception, the method parseString must declare that it throws the Exception if you want to the exception to propagate.
But throws Exception is saying that this method could throw any possible checked exception ... which makes life difficult for the caller. (Not in this example ... but in general.)
My advice is as follows:
Avoid creating / throwing Exception. Pick a more specific (checked or unchecked) exception that reflects the meaning of the "exceptional event" you are trying to report ... or implement your own exception class. In this case throwing IllegalArgumentException would probably be better, though that is an unchecked exception.
Avoid situations where you need to propagate Exception.
Be careful when you catch Exception. It catches every (non-Error) exception, including all of the unchecked ones; i.e. RuntimeExecption and its subclasses.
You either don't catch it in ParseString, or you rethrow it with throw e;
Once an exception is caught, it doesn't get propagated unless you throw it again.
Examine what you're doing here:
try {
throw new Exception("bad formatted N-triples");//You throw an exception!
} catch (Exception e) {//And immediately catch it!
e.printStackTrace();
}
Because the exception is caught, it will not propagate. Instead, remove the try/catch block and simply throw the exception:
void ParseString(String s){
if (matcher.matches()) {
//code for reasons
} else {
//throw exception
throw new Exception("bad formatted N-triples");
}
}
Note that this is actually bad practice. You want to say something about your exception, and declare it:
void ParseString(String s) throws IllegalArgumentException {
if (matcher.matches()) {
//code for reasons
} else {
//throw exception
throw new IllegalArgumentException("bad formatted N-triples");
}
}
The surrounding function should know how to cope with that exception explicitly, rather than just throwing it's hands up because it's a general exception.
You shouldn't surround your error with try/catch:
void ParseString(String s){
if (matcher.matches()) {
}
else{
//throw exception
throw new Exception("bad formatted N-triples");}
}
}
When you throw the error, it's caught in the catch statement within parseString method, which is why isn't isn't propagated to the top.
Ideally, you'd do:
void ParseString(String s) throws Exception {
if (matcher.matches()) {
}
else{
//throw exception
throw new Exception("bad formatted N-triples");}
}
}
In trying to refactor some I code I attempted to throw the exception in the catch clause like so -
try {
....
}
catch(Exception exception){
.....
throw exception
}
However when I attempted to throw the exception on line "throw exception" the compiler complained with a message that I needed to surround my throw clause in a new try/catch like so -
try
{
....
}
catch (Exception exception)
{
.....
try
{
throw exception
}
catch (Exception e2)
{
...
}
}
Why does the compiler require this and what use does it provide ?
Thanks
The exception java.lang.Exception is a checked exception. This means that it must either be declared in the throws clause of the enclosing method or caught and handled withing the method body.
However, what you are doing in your "fixed" version is to catch the exception, rethrow it and then immediately catch it again. That doesn't make much sense.
Without seeing the real code, it is not clear what the real solution should be, but I expect that the problem is in the original try { ... } catch handler:
If possible, you should catch a more specific exception at that point, so that when you rethrow it, it is covered by the method's existing throws list.
Alternatively, you could wrap the exception in an unchecked exception and throw that instead.
As a last resort, you could change the signature of the method to include Exception in the throws list. But that's a really bad idea, because it just pushes the problem off to the caller ... and leaves the developer / reader in the position of not knowing what exceptions to expect.
In Java, there is a distinction between checked and unchecked exceptions. An unchecked exception can essentially be thrown at any place in code and, if it's not caught somewhere, it will propagate up to the entry point of your application and then stop the process (usually with an error message and stack trace). A checked exception is different: The compiler won't let you just let it propagate, you need to either surround any code which might throw a checked exception with try-catch blocks (and "throw exception" is the simplest case if exception is an instance of a checked exception class) or you must mark the method which contains the call to code that might throw a checked exception with a "throws" declaration. If the desired behaviour is to throw an unchecked exception, then you'll need to wrap the exception in a RuntimeException. If the desired behaviour is to keep the exception checked, then you'll need to add a throws declaration to your current method.
In your original code, nothing catches the thrown exception. I would imagine you either have to specify that your function throws an exception or have another try/catch block as the compiler suggests to catch it.
Instead of
public void yourFunction(){
try {
....
}
catch(Exception exception){
.....
throw exception
}
}
try
public void yourFunction() throws Exception{
try {
....
}
catch(Exception exception){
.....
throw exception
}
}
My guess is that your trying to throw an exception sub class that isn't declared by the method as an exception type it can throw.
The following example works
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws Exception{
try {
int value = 1/0;
} catch (Exception e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
However this example will give an error.
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws RuntimeException{
try {
int value = 1/0;
} catch (Exception e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
Note in the second example I'm simply catching Exception not RuntimeException, it won't compile as I throw Exception which is an undeclared throws, even though I do declare RuntimeException.
Yes the exception is a RuntimeException but the compiler doesn't know that.
Just thought of a third working example to show you. This one also works because your throwing the same type as you declare. (note the only change is the catch block)
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws RuntimeException{
try {
int value = 1/0;
} catch (RuntimeException e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
You need to understand the differences between all three of these answers
Here's the code:
public class Exc {
int x = 2;
public void throwE(int p) throws Excp, Excp2 {
if(x==p) {
throw new Excp();
}
else if(x==(p+2)) {
throw new Excp2();
}
}
}
Here's the handler code:
public class tdExc {
public static void main(String[] args) {
Exc testObj = new Exc();
try {
testObj.throwE(0);
System.out.println("This will never be printed, so sad...");
} catch(Exception Excp) {
System.out.println("Caught ya!");
} catch(Exception Excp2) {
System.out.println("Caught ya! Again!!!!");
} finally {
System.out.println("This will always be printed!");
}
}
}
Excp and Excp2 both extends Exception and have similar code(nothing). Now I'm getting the error Exception has already been caught error at Excp2, regardless of whether I supply 2 or 0 to throwE method.
You're looking for:
try
{ }
catch(Excp excp)
{
log(excp);
}
catch(Excp2 excp2)
{
log(excp2);
}
finally
{ }
When you catch an exception, to specify the type of the exception, and the name of of its reference.
Your original code tried to catch Exception, which is the least specific exception, so you cannot catch anything after that.
When you are catching an exception, you have to specify what type of exception you are catching, this will allow you to better handle the exception that has occured. One thing that you have to keep in mind though, is that there is that there are specific and other more "wide purpose" exceptions.
For instance, NumberFormatException is more specific than Exception, since NumberFormatException will be thrown whenever you will try to parse a string into a number.
Thus, when having multiple catch statements, always put the most specific one on top, and the more generic ones at the end. If you put the more generic ones at the beginning, they will catch the exception before it can be passed to a more specific catch statement.
In your case, you are trying to catch the same exception twice, since you have two catch statements that try to catch the same exception.
Java dispatches to the catch() clauses based on the types of the exception: your clauses are both trying to catch an exception of type Exception, and give them the names Excp and Excp2:
public class tdExc {
public static void main(String[] args) {
Exc testObj = new Exc();
try {
testObj.throwE(0);
System.out.println("This will never be printed, so sad...");
} catch(Exception Excp) {
Shouldn't this be Excp e?
System.out.println("Caught ya!");
} catch(Exception Excp2) {
Shouldn't this be Excp2 e?
System.out.println("Caught ya! Again!!!!");
} finally {
System.out.println("This will always be printed!");
}
}
}
And, while it's unrelated, I think your earlier code would be easier for you to think about if you write it more like this:
public void throwE(boolean p) throws Excp, Excp2 {
if(p) {
throw new Excp();
} else {
throw new Excp2();
}
}
Call it with true or false as parameters.
I believe the exception can only be caught once with java. The first exception handler will process the error.
Please someone tel me if this is true for java :)