JDK 9 RFR of JDK-8168681: Correct deprecation text for Class.newInstance (original) (raw)
joe darcy joe.darcy at oracle.com
Thu Nov 3 00:51:51 UTC 2016
- Previous message: Proposal for adding O_DIRECT support into JDK 9
- Next message: JDK 9 RFR of JDK-8168681: Correct deprecation text for Class.newInstance
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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 * *
{@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
- Previous message: Proposal for adding O_DIRECT support into JDK 9
- Next message: JDK 9 RFR of JDK-8168681: Correct deprecation text for Class.newInstance
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]