Why is InstantiationException a checked exception?
My understanding is that checked exceptions are those that the caller of the can reasonably be expected to recover from. I don't understand why this is the case with InstantiationException. If a class cannot be instantiated then what 开发者_开发百科is the caller expected to do?
I then thought that maybe it was an important consideration that the code had compiled - therefore this could only happen if a class is dynamically specified.1 In this case the class may be more like a parameter, but then we have IllegalArgumentException that is a runtime exception.
What is the rational behind which standard exceptions are checked, and which are not?
1 Is this true?
One reason for explicitly handling this exception that I can think of (but that's not an authoritative answer):
Try instanciating a class with reflection (because that class is configured, not statically linked). If it doesn't have the expected constructor signature, try another constructor. Or another class. Any framework code (such as Spring) might have such logic.
From the JavaDoc for InstantiationException:
Thrown when an application tries to create an instance of a class using the newInstance method in class Class, but the specified class object cannot be instantiated because it is an interface or is an abstract class.
This will only happen when using Java reflection, e.g. when programmatically instantiating objects, e.g. ClassName.class.newInstance()
as opposed to new ClassName()
so to speak. It is only natural to expect whoever uses reflection to write code that handles any such aberrations like instantiating an abstract class or an interface or if there is an exception thrown in during the constructor invocation (in which case you can use e.getCause()
).
It is not expected to be handled in your code -- but rather by that particular API/library that uses reflection.
Class.newInstance() has an interesting description on when an InstanciationException is thrown [javadoc] :
InstantiationException - if this Class represents an abstract class, an interface, an array class, a primitive type, or void; or if the class has no nullary constructor; or if the instantiation fails for some other reason.
To me it looks like it tries to cover for all cases a statically linked class' instantiation would fail at compile time.
The most important part is the piece I highlighted though. Imagine a constructor that throws a checked exception. What happens if that constructor is called dynamically? Who'll check for that poor checked exception?
As you can see from javadoc of InstantiationException javadoc, it's thrown
when an application tries to create an instance of a class using the newInstance method in class Class, but the specified class object cannot be instantiated.
you can perfectly write such code:
try {
Class myClass = Class.forName("Myclass");
myClass.newInstance();
} catch (ClassNotFoundException e) {
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
}
no IllegalArgumentException
will be thrown.
About checked
and unchecked
it's more about what caused the exception, not whether it's easy to recover from or not. Please read more about checked
vs
While there's a vast grey area between check and unchecked exceptions, and many exceptions can be arguably designed one way or the other, this one is not. It is a mistake, it should have been unchecked.
精彩评论