...
Any checked exception thrown by the default constructor of Class.newInstance()
is propagated to the caller, even though Class.newInstance()
declares that it throws only InstantiationException
and IllegalAccessException
. This noncompliant code example demonstrates one way to use Class.newInstance()
to throw arbitrary exceptions, whether checked or and unchecked exceptions.
This noncompliant code example also violates ERR13-J. Do not throw RuntimeException and ERR14-J. Do not catch RuntimeException.
Code Block | ||
---|---|---|
| ||
public class NewInstance {
private static Throwable throwable;
private NewInstance() throws Throwable {
throw throwable;
}
public static synchronized void undeclaredThrow(Throwable throwable) {
// These exceptions should not be passed
if (throwable instanceof IllegalAccessException ||
throwable instanceof InstantiationException) {
throw new IllegalArgumentException(); // Unchecked, no declaration required
}
NewInstance.throwable = throwable;
try {
// next line throws the Throwable argument passed in above,
// even though the throws clause of class.newInstance fails
// to declare that this may happen; see JavaDoc
NewInstance.class.newInstance();
} catch (InstantiationException e) { /* unreachable */
} catch (IllegalAccessException e) { /* unreachable */
} finally { // Avoid memory leak
NewInstance.throwable = null;
}
}
}
public class UndeclaredException {
public static void main(String[] args) { // No declared checked exceptions
NewInstance.undeclaredThrow(new Exception("Any checked exception"));
}
}
|
Noncompliant Code Example (Class.newInstance()
...
Workarounds)
When the programmer wishes to catch and handle the possible undeclared checked exceptions, the compiler refuses to believe that any can be thrown in the particular context.
The following This noncompliant code example attempts to work around the fact that catch undeclared checked exceptions thrown by Class.newInstance()
can throw undeclared checked exceptions. It catches Exception
and dynamically checks whether the caught exception is an instance of the possible checked exception (carefully re-throwing all other exceptions, of course), as shown below. This approach is fragile, because any unanticipated checked exception bypasses the dynamic check. See ERR14-J. Do not catch RuntimeException for more details.
Code Block | ||
---|---|---|
| ||
public static void main(String[] args) { try { NewInstance.undeclaredThrow(new IOException("Any checked exception")); } catch(Exception e) { if (e instanceof IOException) { System.out.println("IOException occurred"); } else if (e instanceof RuntimeException) { throw (RuntimeException) e; } else { //some other unknown checked exception } } } |
This approach is fragile, because any unanticipated checked exception bypasses the dynamic check. See ERR14-J. Do not catch RuntimeException for more details.
Compliant Solution (java.lang.reflect.Constructor.newInstance()
)
...
Code Block | ||
---|---|---|
| ||
public static synchronized void undeclaredThrow(Throwable throwable) {
// These exceptions should not be passed
if (throwable instanceof IllegalAccessException ||
throwable instanceof InstantiationException ||
throwable instanceof NoSuchMethodException ||
throwable instanceof InvocationTargetException) {
throw new IllegalArgumentException(); // Unchecked, no declaration required
}
NewInstance.throwable = throwable;
try {
Constructor constructor = NewInstance.class.getConstructor( new Class<?>[0] );
constructor.newInstance();
} catch (InstantiationException e) { /* unreachable */
} catch (NoSuchMethodException e) { /* unreachable */
} catch (IllegalAccessException e) { /* unreachable */
} catch (InvocationTargetException e) {
System.out.println("Exception thrat was thrown: " + e.getCause().toString());
} finally { // Avoid memory leak
NewInstance.throwable = null;
}
}
|
...
An unchecked cast of a generic type with parameterized parametrized exception declaration can also result in unexpected checked exceptions. The compiler complains Any attempt to do so is diagnosed by the compiler, unless the warnings are suppressed.
...
Note that Thread.stop()
is deprecated, and so this code also violates MET15-J. Do not use deprecated or obsolete classes or methods).
Noncompliant Code Example (
...
Bytecode Manipulation)
Wiki Markup |
---|
It is also possible to disassemble a class, remove any declared checked exceptions and reassemble the class so that checked exceptions are thrown at runtime when the class is used \[[Roubtsov 2003|AA. Bibliography#Roubtsov 03]\]. Compiling against a class that declares the checked exception and supplying at runtime a class that lacks the declaration also suffices. Similarly, a compiler other than {{javac}} might handle checked exceptions differently. Undeclared checked exceptions can also be produced through crafted use of the {{sun.corba.Bridge}} class. All these methods are strongly discouraged. |
...