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


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

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