< prev index next >

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

Print this page

187     public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
188         return langReflectAccess.getExecutableSharedParameterTypes(ex);
189     }
190 
191     public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
192         throws IllegalAccessException, InstantiationException, InvocationTargetException
193     {
194         return langReflectAccess.newInstance(ctor, args, caller);
195     }
196 
197     //--------------------------------------------------------------------------
198     //
199     // Routines used by serialization
200     //
201     //
202 
203     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
204         if (!Externalizable.class.isAssignableFrom(cl)) {
205             return null;
206         }



207         try {
208             Constructor<?> cons = cl.getConstructor();
209             cons.setAccessible(true);
210             return cons;
211         } catch (NoSuchMethodException ex) {
212             return null;
213         }
214     }
215 
216     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
217                                                                Constructor<?> constructorToCall)
218     {
219         if (constructorToCall.getDeclaringClass() == cl) {
220             constructorToCall.setAccessible(true);
221             return constructorToCall;
222         }



223         return generateConstructor(cl, constructorToCall);
224     }
225 
226     /**
227      * Given a class, determines whether its superclass has
228      * any constructors that are accessible from the class.
229      * This is a special purpose method intended to do access
230      * checking for a serializable class and its superclasses
231      * up to, but not including, the first non-serializable
232      * superclass. This also implies that the superclass is
233      * always non-null, because a serializable class must be a
234      * class (not an interface) and Object is not serializable.
235      *
236      * @param cl the class from which access is checked
237      * @return whether the superclass has a constructor accessible from cl
238      */
239     private boolean superHasAccessibleConstructor(Class<?> cl) {
240         Class<?> superCl = cl.getSuperclass();
241         assert Serializable.class.isAssignableFrom(cl);
242         assert superCl != null;

262                     return true;
263                 }
264             }
265             return false;
266         }
267     }
268 
269     /**
270      * Returns a constructor that allocates an instance of cl and that then initializes
271      * the instance by calling the no-arg constructor of its first non-serializable
272      * superclass. This is specified in the Serialization Specification, section 3.1,
273      * in step 11 of the deserialization process. If cl is not serializable, returns
274      * cl's no-arg constructor. If no accessible constructor is found, or if the
275      * class hierarchy is somehow malformed (e.g., a serializable class has no
276      * superclass), null is returned.
277      *
278      * @param cl the class for which a constructor is to be found
279      * @return the generated constructor, or null if none is available
280      */
281     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {




282         Class<?> initCl = cl;
283         while (Serializable.class.isAssignableFrom(initCl)) {
284             Class<?> prev = initCl;
285             if ((initCl = initCl.getSuperclass()) == null ||
286                 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
287                 return null;
288             }
289         }
290         Constructor<?> constructorToCall;
291         try {
292             constructorToCall = initCl.getDeclaredConstructor();
293             int mods = constructorToCall.getModifiers();
294             if ((mods & Modifier.PRIVATE) != 0 ||
295                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
296                             !packageEquals(cl, initCl))) {
297                 return null;
298             }
299         } catch (NoSuchMethodException ex) {
300             return null;
301         }

187     public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
188         return langReflectAccess.getExecutableSharedParameterTypes(ex);
189     }
190 
191     public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
192         throws IllegalAccessException, InstantiationException, InvocationTargetException
193     {
194         return langReflectAccess.newInstance(ctor, args, caller);
195     }
196 
197     //--------------------------------------------------------------------------
198     //
199     // Routines used by serialization
200     //
201     //
202 
203     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
204         if (!Externalizable.class.isAssignableFrom(cl)) {
205             return null;
206         }
207         if (cl.isValue()) {
208             throw new UnsupportedOperationException("newConstructorForExternalization does not support value classes");
209         }
210         try {
211             Constructor<?> cons = cl.getConstructor();
212             cons.setAccessible(true);
213             return cons;
214         } catch (NoSuchMethodException ex) {
215             return null;
216         }
217     }
218 
219     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
220                                                                Constructor<?> constructorToCall)
221     {
222         if (constructorToCall.getDeclaringClass() == cl) {
223             constructorToCall.setAccessible(true);
224             return constructorToCall;
225         }
226         if (cl.isValue()) {
227             throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes");
228         }
229         return generateConstructor(cl, constructorToCall);
230     }
231 
232     /**
233      * Given a class, determines whether its superclass has
234      * any constructors that are accessible from the class.
235      * This is a special purpose method intended to do access
236      * checking for a serializable class and its superclasses
237      * up to, but not including, the first non-serializable
238      * superclass. This also implies that the superclass is
239      * always non-null, because a serializable class must be a
240      * class (not an interface) and Object is not serializable.
241      *
242      * @param cl the class from which access is checked
243      * @return whether the superclass has a constructor accessible from cl
244      */
245     private boolean superHasAccessibleConstructor(Class<?> cl) {
246         Class<?> superCl = cl.getSuperclass();
247         assert Serializable.class.isAssignableFrom(cl);
248         assert superCl != null;

268                     return true;
269                 }
270             }
271             return false;
272         }
273     }
274 
275     /**
276      * Returns a constructor that allocates an instance of cl and that then initializes
277      * the instance by calling the no-arg constructor of its first non-serializable
278      * superclass. This is specified in the Serialization Specification, section 3.1,
279      * in step 11 of the deserialization process. If cl is not serializable, returns
280      * cl's no-arg constructor. If no accessible constructor is found, or if the
281      * class hierarchy is somehow malformed (e.g., a serializable class has no
282      * superclass), null is returned.
283      *
284      * @param cl the class for which a constructor is to be found
285      * @return the generated constructor, or null if none is available
286      */
287     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
288         if (cl.isValue()) {
289             throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes: " + cl);
290         }
291 
292         Class<?> initCl = cl;
293         while (Serializable.class.isAssignableFrom(initCl)) {
294             Class<?> prev = initCl;
295             if ((initCl = initCl.getSuperclass()) == null ||
296                 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
297                 return null;
298             }
299         }
300         Constructor<?> constructorToCall;
301         try {
302             constructorToCall = initCl.getDeclaredConstructor();
303             int mods = constructorToCall.getModifiers();
304             if ((mods & Modifier.PRIVATE) != 0 ||
305                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
306                             !packageEquals(cl, initCl))) {
307                 return null;
308             }
309         } catch (NoSuchMethodException ex) {
310             return null;
311         }
< prev index next >