There are two further aspects that need to be considered when following the recommendation in the Javadoc by replacing:
clz.newInstance()
with:
clz.getDeclaredConstructor().newInstance()
Firstly, Class#getDeclaredConstructor may throw InvocationTargetException or NoSuchMethodException (both forms of ReflectiveOperationException), where as Class#newInstance throws InstantiationException for these conditions.
As these are not types of RuntimeException, they need to be explicitly handled, arguably by catching them and setting them as a cause for a (new) InstantiationException that can be thrown, to preserve the signature for the calling code.
Secondly, Class#getDeclaredConstructor can cause an additional "accessDeclaredMembers" security check to be made (as well as the checkPackageAccess() check that Class#newInstance also makes).
Therefore, additional steps (such as the use of AccessController#doPrivileged) may need to be taken to ensure the caller does not fail this additional check.
So, a method like this:
Object createInstance(Class clz)
throws InstantiationException, IllegalAccessException {
return clz.newInstance();
}
might, once correctly modified, look something more like this:
Object createInstance(Class<?> clz)
throws InstantiationException, IllegalAccessException {
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws InstantiationException, IllegalAccessException {
try {
return clz.getDeclaredConstructor().newInstance();
} catch (InvocationTargetException|NoSuchMethodException e) {
throw (InstantiationException)((new InstantiationException()).initCause(e));
}
}
});
} catch (PrivilegedActionException pae) {
Exception e = pae.getException();
if (e instanceof InstantiationException) throw (InstantiationException)e;
throw (IllegalAccessException)e;
}
}