Ryan Delucchi asked here in comment #3 to Tom Hawtin's answer:
why is Class.newInstance() "evil"?
this in response to the code sample:
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
so, why is it Evil?
The Java API documentation explains why (http://java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance()):
Note that this method propagates any exception thrown by the nullary constructor, including a checked exception. Use of this method effectively bypasses the compile-time exception checking that would otherwise be performed by the compiler. The Constructor.newInstance method avoids this problem by wrapping any exception thrown by the constructor in a (checked) InvocationTargetException.
In other words, it can defeat the checked exceptions system.
One more reason:
Modern IDEs allow you to find class usages - it helps during refactoring, if you and your IDE know what code is using class that you plan to change.
When you don't do an explicit usage of the constructor, but use Class.newInstance() instead, you risk not to find that usage during refactoring and this problem will not manifest itself when you compile.
I don't know why no one provided a simple example based explanation to this, as compared to Constructor::newInstance for example, since finally Class::newInstance was deprecated since java-9.
Suppose you have this very simple class (does not matter that it is broken):
static class Foo {
public Foo() throws IOException {
throw new IOException();
}
}
And you try to create an instance of it via reflection. First Class::newInstance:
Class<Foo> clazz = ...
try {
clazz.newInstance();
} catch (InstantiationException e) {
// handle 1
} catch (IllegalAccessException e) {
// handle 2
}
Calling this will result in a IOException being thrown - problem is that your code does not handle it, neither handle 1 nor handle 2 will catch it.
In contrast when doing it via a Constructor:
Constructor<Foo> constructor = null;
try {
constructor = clazz.getConstructor();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
Foo foo = constructor.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
System.out.println("handle 3 called");
e.printStackTrace();
}
that handle 3 will be called, thus you will handle it.
Effectively, Class::newInstance bypasses the exception handling - which you really don't want.
Related
I should know this, but for some reason I can't figure it out right now.
Is there a way to rewrite this code to avoid instanceof?
try {
//Exceptions may happen
} catch (Exception1 exception1) {
//do stuff only in case of Exception1
} catch(Exception e) {
// do stuff in all exception cases except Exception1
if (e instanceof Exception2) {
// do stuff only in case of Exception2
}
}
If you're going to have your exception handling for Exception inline, and don't want to repeat it, then the only solution is the OP solution.
However, if you can put the common exception handling into a function, then this would be neat:
try {
//Exceptions may happen
} catch (Exception1 exception1) {
//do stuff only in case of Exception1
} catch(Exception2 e) {
doCommonStuff();
doException2Stuff();
} catch(Exception e) {
doCommonStuff();
}
However, the above may lead to a small problem in terms of whether you want to pass control to outside of the try/catch block, or whether you're hoping to return a value, or even throw another exception.
You may find that although all paths of your code DO throw an exception, that the above construct, of using common exception handler methods, may look to the compiler like some control paths don't.
You can, therefore, express a common exception handler, that always throws an exception like this:
private <T> T throwLastException(Exception2 input) {
// blah blah blah
throw new SomeException();
}
and this can be called as part of a return statement that appears to guarantee the calling function returns a value, when in fact it's just telling the compiler not to worry :)
Without any further context IMO the following is good enough:
try {
//Exceptions may happen
} catch (Exception1 exception1) {
//do stuff only in case of Exception1
} catch (Exception2 exception2) {
some_method();
}
catch(Exception e) {
some_method();
}
Where some_method would encapsulate the code related with "// do stuff in all exception cases except Exception1"
Consider encapsulating common code between catch clauses 2 & 3 on some method, for instance:
try {
//code
} catch (Exception1 e1) {
// specific code for exception 1
} catch (Exception2 e2) {
// specific code for exception 2
method();
} catch (Exception e) {
method();
}
Catch two types of exception in one block with the "|" operator.. And maybe you can execute code that you have to execute in any case in the finally statement. That are all options you have, and i think creating a method and calling it isn't a option, when you're trying to make your code more readable, what I think you're trying to do
try {
//code
} catch (Exception1 | Exception2 e2) {
// specific code for exception 1 & 2
} catch (Exception e) {
// handle other exceptions
} finally {
// execute in any case
}
I have a method with a checked exception for a parent class, which can throw exceptions of the type parent and subclass
public void method() throws ParentException {
if( false ) throw new ParentException();
else if( true ) throw new ChildException(); // this one is thrown
}
and I have a cascade catch block, which first has the child exception
try {
method();
} catch (ChildException e) {
// I get here?
} catch (ParentException e) {
// or here?
}
Which block will catch the exception thrown? Since the method declares explicitly the ParentException only, would the ChildException be shown as an instance of ParentException?
The catch block will always catch the most specific exception available to it, working its way up from the inheritance hierarchy.
I should stress that your catch blocks must be in the inheritance hierarchy order; that is to say, you may not declare a catch block with ParentException followed by ChildException, as that is a compilation error. What you have there (in terms of catch blocks) is valid.
A more common use case of this is when handling file IO; you can first catch FileNotFoundException, then IOException, should the error be less specific than FileNotFoundException.
For a project I've been working on, we have some blocks that look like this:
Class A:
try {
callSomeMethod();
}
catch (Exception e) {
throw new SomeCustomExceptionTypeForMetrics("");
}
However, I was tasked with replacing all instances where we catch generic exceptions with only specific "expected" types of exceptions.
The problem is callSomeMethod() has something like this
Class B:
try {
if (someCondition...) {
}
else {
//failed
throw new RuntimeException("Timeout while waiting for results")
}
}
catch(InterruptedException e) {
// do some failure stuff here
throw new RuntimeException("Something here");
}
Ideally, my group has asked me to change as little as possible, and I can't change the signature for callSomeMethod(), but they also don't want to just catch any RuntimeException in Class A since they don't want to catch just any type of RuntimeException - only the ones we're excepting from Class B.
What is the best way to handle this?
Supposing that your callSomeMethod's signature contains throws Exception, and you can't change it: Change the RuntimeExceptions in the method to a custom Exception class, and then in Class A:
try {
callSomeMethod();
}
catch (Exception e) {
if(e instanceof CustomException)
//Log it or something, for metrics?
}
This is kind of silly, but might be necessary if you can't change the method signature. (If you can change it, you could catch the CustomException directly.) You could even make a method in your logger that takes an Exception, checks what type it is, and acts accordingly. Then just use this method in every catch statement that you need to edit.
While designing this solution, keep in mind that RuntimeExceptions don't need to be caught. It could save you some trouble.
If you chnage your code in class B as below
try {
if (someCondition...) {
}
else {
//failed
throw new MyRuntimeException("Timeout while waiting for results")
}
}
catch(InterruptedException e) {
// do some failure stuff here
throw new MyRuntimeException("Something here");
}
and define MyRuntimeException as :
class MyRuntimeException extends RuntimeException{
..
}
In class A, you only need to catch MyRuntimeException exception .
Hope this solve your problem!!
I am new to Java and I was looking at exception handling. When we catch java exceptions, we declare and use an Object of the Exception class without initializing it, i.e.
catch(NullPointerException e)
e.printStackTrace();
So my question is, how are we able to use object reference e without instantiating it?
They are well instantiated:
void example() {
throw new UnsupportedOperationException("message");
} // ^^^
void demonstration() {
try {
example();
} catch (UnsupportedOperationException e) {
e.printStackTrace();
}
}
This very simple example should be pretty self explanatory...
The exception is (often) instantiated when the error occurs with a throw statement. For example,
throw new NullPointerException();
(Note that this is just an example. NPEs are not usually explicitly thrown in your own code.)
The catch clause is similar to a function that declares a parameter. Consider the function
void func(String s) {
// ...
}
func does not instantiate the s. The String is created somewhere else and passed to the function. In the same way, we create an exception with throw and it is "passed" to the catch clause kind of like a parameter.
Yes, reference e in catch(NullPointerException e) is for the possible exception thrown in code using throw new NullPointerException("some error message");
The exception is instantiated. It happens internally in the class that can potentially throw an exception. For your information, the keyword throw is responsible to create and throw the exception. Your catch method will catch the exception. You can also implement your own exceptions using this keyword.
This question already has answers here:
Can I catch multiple Java exceptions in the same catch clause?
(10 answers)
Closed 8 years ago.
I need to catch two exceptions because they require the same handling logic. I would like to do something like:
catch (Exception e, ExtendsRuntimeException re) {
// common logic to handle both exceptions
}
Is it possible to avoid duplicating the handler code in each catch block?
Java 7 and later
Multiple-exception catches are supported, starting in Java 7.
The syntax is:
try {
// stuff
} catch (Exception1 | Exception2 ex) {
// Handle both exceptions
}
The static type of ex is the most specialized common supertype of the exceptions listed. There is a nice feature where if you rethrow ex in the catch, the compiler knows that only one of the listed exceptions can be thrown.
Java 6 and earlier
Prior to Java 7, there are ways to handle this problem, but they tend to be inelegant, and to have limitations.
Approach #1
try {
// stuff
} catch (Exception1 ex) {
handleException(ex);
} catch (Exception2 ex) {
handleException(ex);
}
public void handleException(SuperException ex) {
// handle exception here
}
This gets messy if the exception handler needs to access local variables declared before the try. And if the handler method needs to rethrow the exception (and it is checked) then you run into serious problems with the signature. Specifically, handleException has to be declared as throwing SuperException ... which potentially means you have to change the signature of the enclosing method, and so on.
Approach #2
try {
// stuff
} catch (SuperException ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
// handle exception
} else {
throw ex;
}
}
Once again, we have a potential problem with signatures.
Approach #3
try {
// stuff
} catch (SuperException ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
// handle exception
}
}
If you leave out the else part (e.g. because there are no other subtypes of SuperException at the moment) the code becomes more fragile. If the exception hierarchy is reorganized, this handler without an else may end up silently eating exceptions!
Java <= 6.x just allows you to catch one exception for each catch block:
try {
} catch (ExceptionType name) {
} catch (ExceptionType name) {
}
Documentation:
Each catch block is an exception handler and handles the type of
exception indicated by its argument. The argument type, ExceptionType,
declares the type of exception that the handler can handle and must be
the name of a class that inherits from the Throwable class.
For Java 7 you can have multiple Exception caught on one catch block:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
Documentation:
In Java SE 7 and later, a single catch block can handle more than one
type of exception. This feature can reduce code duplication and lessen
the temptation to catch an overly broad exception.
Reference:
http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
If you aren't on java 7, you can extract your exception handling to a method - that way you can at least minimize duplication
try {
// try something
}
catch(ExtendsRuntimeException e) { handleError(e); }
catch(Exception e) { handleError(e); }
For Java < 7 you can use if-else along with Exception:
try {
// common logic to handle both exceptions
} catch (Exception ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
}
else {
throw ex;
// or if you don't want to have to declare Exception use
// throw new RuntimeException(ex);
}
}
Edited and replaced Throwable with Exception.
http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html covers catching multiple exceptions in the same block.
try {
// your code
} catch (Exception1 | Exception2 ex) {
// Handle 2 exceptions in Java 7
}
I'm making study cards, and this thread was helpful, just wanted to put in my two cents.
Before the launch of Java SE 7 we were habitual of writing code with multiple catch statements associated with a try block.
A very basic Example:
try {
// some instructions
} catch(ATypeException e) {
} catch(BTypeException e) {
} catch(CTypeException e) {
}
But now with the latest update on Java, instead of writing multiple catch statements we can handle multiple exceptions within a single catch clause. Here is an example showing how this feature can be achieved.
try {
// some instructions
} catch(ATypeException|BTypeException|CTypeException ex) {
throw e;
}
So multiple Exceptions in a single catch clause not only simplifies the code but also reduce the redundancy of code.
I found this article which explains this feature very well along with its implementation.
Improved and Better Exception Handling from Java 7
This may help you too.