< prev index next >

src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java

Print this page

217     public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
218         return langReflectAccess.getExecutableSharedParameterTypes(ex);
219     }
220 
221     public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
222         throws IllegalAccessException, InstantiationException, InvocationTargetException
223     {
224         return langReflectAccess.newInstance(ctor, args, caller);
225     }
226 
227     //--------------------------------------------------------------------------
228     //
229     // Routines used by serialization
230     //
231     //
232 
233     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
234         if (!Externalizable.class.isAssignableFrom(cl)) {
235             return null;
236         }



237         try {
238             Constructor<?> cons = cl.getConstructor();
239             cons.setAccessible(true);
240             return cons;
241         } catch (NoSuchMethodException ex) {
242             return null;
243         }
244     }
245 
246     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
247                                                                Constructor<?> constructorToCall)
248     {
249         if (constructorToCall.getDeclaringClass() == cl) {
250             constructorToCall.setAccessible(true);
251             return constructorToCall;
252         }



253         return generateConstructor(cl, constructorToCall);
254     }
255 
256     /**
257      * Given a class, determines whether its superclass has
258      * any constructors that are accessible from the class.
259      * This is a special purpose method intended to do access
260      * checking for a serializable class and its superclasses
261      * up to, but not including, the first non-serializable
262      * superclass. This also implies that the superclass is
263      * always non-null, because a serializable class must be a
264      * class (not an interface) and Object is not serializable.
265      *
266      * @param cl the class from which access is checked
267      * @return whether the superclass has a constructor accessible from cl
268      */
269     private boolean superHasAccessibleConstructor(Class<?> cl) {
270         Class<?> superCl = cl.getSuperclass();
271         assert Serializable.class.isAssignableFrom(cl);
272         assert superCl != null;

292                     return true;
293                 }
294             }
295             return false;
296         }
297     }
298 
299     /**
300      * Returns a constructor that allocates an instance of cl and that then initializes
301      * the instance by calling the no-arg constructor of its first non-serializable
302      * superclass. This is specified in the Serialization Specification, section 3.1,
303      * in step 11 of the deserialization process. If cl is not serializable, returns
304      * cl's no-arg constructor. If no accessible constructor is found, or if the
305      * class hierarchy is somehow malformed (e.g., a serializable class has no
306      * superclass), null is returned.
307      *
308      * @param cl the class for which a constructor is to be found
309      * @return the generated constructor, or null if none is available
310      */
311     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {




312         Class<?> initCl = cl;
313         while (Serializable.class.isAssignableFrom(initCl)) {
314             Class<?> prev = initCl;
315             if ((initCl = initCl.getSuperclass()) == null ||
316                 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
317                 return null;
318             }
319         }
320         Constructor<?> constructorToCall;
321         try {
322             constructorToCall = initCl.getDeclaredConstructor();
323             int mods = constructorToCall.getModifiers();
324             if ((mods & Modifier.PRIVATE) != 0 ||
325                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
326                             !packageEquals(cl, initCl))) {
327                 return null;
328             }
329         } catch (NoSuchMethodException ex) {
330             return null;
331         }

217     public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
218         return langReflectAccess.getExecutableSharedParameterTypes(ex);
219     }
220 
221     public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
222         throws IllegalAccessException, InstantiationException, InvocationTargetException
223     {
224         return langReflectAccess.newInstance(ctor, args, caller);
225     }
226 
227     //--------------------------------------------------------------------------
228     //
229     // Routines used by serialization
230     //
231     //
232 
233     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
234         if (!Externalizable.class.isAssignableFrom(cl)) {
235             return null;
236         }
237         if (cl.isValue()) {
238             throw new UnsupportedOperationException("newConstructorForExternalization does not support value classes");
239         }
240         try {
241             Constructor<?> cons = cl.getConstructor();
242             cons.setAccessible(true);
243             return cons;
244         } catch (NoSuchMethodException ex) {
245             return null;
246         }
247     }
248 
249     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
250                                                                Constructor<?> constructorToCall)
251     {
252         if (constructorToCall.getDeclaringClass() == cl) {
253             constructorToCall.setAccessible(true);
254             return constructorToCall;
255         }
256         if (cl.isValue()) {
257             throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes");
258         }
259         return generateConstructor(cl, constructorToCall);
260     }
261 
262     /**
263      * Given a class, determines whether its superclass has
264      * any constructors that are accessible from the class.
265      * This is a special purpose method intended to do access
266      * checking for a serializable class and its superclasses
267      * up to, but not including, the first non-serializable
268      * superclass. This also implies that the superclass is
269      * always non-null, because a serializable class must be a
270      * class (not an interface) and Object is not serializable.
271      *
272      * @param cl the class from which access is checked
273      * @return whether the superclass has a constructor accessible from cl
274      */
275     private boolean superHasAccessibleConstructor(Class<?> cl) {
276         Class<?> superCl = cl.getSuperclass();
277         assert Serializable.class.isAssignableFrom(cl);
278         assert superCl != null;

298                     return true;
299                 }
300             }
301             return false;
302         }
303     }
304 
305     /**
306      * Returns a constructor that allocates an instance of cl and that then initializes
307      * the instance by calling the no-arg constructor of its first non-serializable
308      * superclass. This is specified in the Serialization Specification, section 3.1,
309      * in step 11 of the deserialization process. If cl is not serializable, returns
310      * cl's no-arg constructor. If no accessible constructor is found, or if the
311      * class hierarchy is somehow malformed (e.g., a serializable class has no
312      * superclass), null is returned.
313      *
314      * @param cl the class for which a constructor is to be found
315      * @return the generated constructor, or null if none is available
316      */
317     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
318         if (cl.isValue()) {
319             throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes: " + cl);
320         }
321 
322         Class<?> initCl = cl;
323         while (Serializable.class.isAssignableFrom(initCl)) {
324             Class<?> prev = initCl;
325             if ((initCl = initCl.getSuperclass()) == null ||
326                 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
327                 return null;
328             }
329         }
330         Constructor<?> constructorToCall;
331         try {
332             constructorToCall = initCl.getDeclaredConstructor();
333             int mods = constructorToCall.getModifiers();
334             if ((mods & Modifier.PRIVATE) != 0 ||
335                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
336                             !packageEquals(cl, initCl))) {
337                 return null;
338             }
339         } catch (NoSuchMethodException ex) {
340             return null;
341         }
< prev index next >