JDK 9 RFR of JDK-8168681: Correct deprecation text for Class.newInstance
joe darcy
joe.darcy at oracle.com
Thu Nov 3 00:51:51 UTC 2016
Hello,
As found by Phil Race, the original substitution text for
Class.newInstance (JDK-8159330) is not equivalent in all cases. This
should be addressed. The current suggested replacement text is
"The call
clazz.newInstance()
can be replaced by
clazz.getConstructor().newInstance()"
The getConstructor call only returns *public* constructors while
newInstance can call non-public constructors too, subject to the
appropriate security checks.
Therefore, using "getDeclaredConstructor()" is a better replacement
since it should be able to find and call non-public constructors when
that is permissible. The patch for this is:
--- a/src/java.base/share/classes/java/lang/Class.java Wed Nov 02
16:24:43 2016 -0700
+++ b/src/java.base/share/classes/java/lang/Class.java Wed Nov 02
17:36:25 2016 -0700
@@ -485,7 +485,7 @@
* can be replaced by
*
* <pre>{@code
- * clazz.getConstructor().newInstance()
+ * clazz.getDeclaredConstructor().newInstance()
* }</pre>
*
* The latter sequence of calls is inferred to be able to throw
I wrote a simple program to try calling constructors with different
access levels private, protected, package (default), and public in
different settings and in the cases I tested clazz.newInstance() and
clazz.getConstructor().newInstance() agreed on both returning an object
or both throwing an exception. This property also held when a security
manager was enabled.
Doing a quick examination of the sources of java.lang.Class,
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC,
Reflection.getCallerClass(), false);
}
// various things elided...
try {
Class<?>[] empty = {};
final Constructor<T> c = getConstructor0(empty,
Member.DECLARED);
// various more things elided...
} catch (NoSuchMethodException e) {
throw (InstantiationException)
new InstantiationException(getName()).initCause(e);
}
}
// still more things elided
}
compared to
public Constructor<T> getDeclaredConstructor(Class<?>...
parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(),
true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
Both alternatives are wrappers around the lower-level getConstructor0
method.
Thanks to Phil for noticing the problem with the existing text.
Cheers,
-Joe
More information about the core-libs-dev
mailing list