252 public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
253 return langReflectAccess.getExecutableSharedParameterTypes(ex);
254 }
255
256 public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
257 throws IllegalAccessException, InstantiationException, InvocationTargetException
258 {
259 return langReflectAccess.newInstance(ctor, args, caller);
260 }
261
262 //--------------------------------------------------------------------------
263 //
264 // Routines used by serialization
265 //
266 //
267
268 public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
269 if (!Externalizable.class.isAssignableFrom(cl)) {
270 return null;
271 }
272 try {
273 Constructor<?> cons = cl.getConstructor();
274 cons.setAccessible(true);
275 return cons;
276 } catch (NoSuchMethodException ex) {
277 return null;
278 }
279 }
280
281 public final Constructor<?> newConstructorForSerialization(Class<?> cl,
282 Constructor<?> constructorToCall)
283 {
284 if (constructorToCall.getDeclaringClass() == cl) {
285 constructorToCall.setAccessible(true);
286 return constructorToCall;
287 }
288 return generateConstructor(cl, constructorToCall);
289 }
290
291 /**
292 * Given a class, determines whether its superclass has
293 * any constructors that are accessible from the class.
294 * This is a special purpose method intended to do access
295 * checking for a serializable class and its superclasses
296 * up to, but not including, the first non-serializable
297 * superclass. This also implies that the superclass is
298 * always non-null, because a serializable class must be a
299 * class (not an interface) and Object is not serializable.
300 *
301 * @param cl the class from which access is checked
302 * @return whether the superclass has a constructor accessible from cl
303 */
304 private boolean superHasAccessibleConstructor(Class<?> cl) {
305 Class<?> superCl = cl.getSuperclass();
306 assert Serializable.class.isAssignableFrom(cl);
307 assert superCl != null;
327 return true;
328 }
329 }
330 return false;
331 }
332 }
333
334 /**
335 * Returns a constructor that allocates an instance of cl and that then initializes
336 * the instance by calling the no-arg constructor of its first non-serializable
337 * superclass. This is specified in the Serialization Specification, section 3.1,
338 * in step 11 of the deserialization process. If cl is not serializable, returns
339 * cl's no-arg constructor. If no accessible constructor is found, or if the
340 * class hierarchy is somehow malformed (e.g., a serializable class has no
341 * superclass), null is returned.
342 *
343 * @param cl the class for which a constructor is to be found
344 * @return the generated constructor, or null if none is available
345 */
346 public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
347 Class<?> initCl = cl;
348 while (Serializable.class.isAssignableFrom(initCl)) {
349 Class<?> prev = initCl;
350 if ((initCl = initCl.getSuperclass()) == null ||
351 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
352 return null;
353 }
354 }
355 Constructor<?> constructorToCall;
356 try {
357 constructorToCall = initCl.getDeclaredConstructor();
358 int mods = constructorToCall.getModifiers();
359 if ((mods & Modifier.PRIVATE) != 0 ||
360 ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
361 !packageEquals(cl, initCl))) {
362 return null;
363 }
364 } catch (NoSuchMethodException ex) {
365 return null;
366 }
|
252 public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
253 return langReflectAccess.getExecutableSharedParameterTypes(ex);
254 }
255
256 public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
257 throws IllegalAccessException, InstantiationException, InvocationTargetException
258 {
259 return langReflectAccess.newInstance(ctor, args, caller);
260 }
261
262 //--------------------------------------------------------------------------
263 //
264 // Routines used by serialization
265 //
266 //
267
268 public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
269 if (!Externalizable.class.isAssignableFrom(cl)) {
270 return null;
271 }
272 if (cl.isValue()) {
273 throw new UnsupportedOperationException("newConstructorForExternalization does not support value classes");
274 }
275 try {
276 Constructor<?> cons = cl.getConstructor();
277 cons.setAccessible(true);
278 return cons;
279 } catch (NoSuchMethodException ex) {
280 return null;
281 }
282 }
283
284 public final Constructor<?> newConstructorForSerialization(Class<?> cl,
285 Constructor<?> constructorToCall)
286 {
287 if (constructorToCall.getDeclaringClass() == cl) {
288 constructorToCall.setAccessible(true);
289 return constructorToCall;
290 }
291 if (cl.isValue()) {
292 throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes");
293 }
294 return generateConstructor(cl, constructorToCall);
295 }
296
297 /**
298 * Given a class, determines whether its superclass has
299 * any constructors that are accessible from the class.
300 * This is a special purpose method intended to do access
301 * checking for a serializable class and its superclasses
302 * up to, but not including, the first non-serializable
303 * superclass. This also implies that the superclass is
304 * always non-null, because a serializable class must be a
305 * class (not an interface) and Object is not serializable.
306 *
307 * @param cl the class from which access is checked
308 * @return whether the superclass has a constructor accessible from cl
309 */
310 private boolean superHasAccessibleConstructor(Class<?> cl) {
311 Class<?> superCl = cl.getSuperclass();
312 assert Serializable.class.isAssignableFrom(cl);
313 assert superCl != null;
333 return true;
334 }
335 }
336 return false;
337 }
338 }
339
340 /**
341 * Returns a constructor that allocates an instance of cl and that then initializes
342 * the instance by calling the no-arg constructor of its first non-serializable
343 * superclass. This is specified in the Serialization Specification, section 3.1,
344 * in step 11 of the deserialization process. If cl is not serializable, returns
345 * cl's no-arg constructor. If no accessible constructor is found, or if the
346 * class hierarchy is somehow malformed (e.g., a serializable class has no
347 * superclass), null is returned.
348 *
349 * @param cl the class for which a constructor is to be found
350 * @return the generated constructor, or null if none is available
351 */
352 public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
353 if (cl.isValue()) {
354 throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes");
355 }
356
357 Class<?> initCl = cl;
358 while (Serializable.class.isAssignableFrom(initCl)) {
359 Class<?> prev = initCl;
360 if ((initCl = initCl.getSuperclass()) == null ||
361 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
362 return null;
363 }
364 }
365 Constructor<?> constructorToCall;
366 try {
367 constructorToCall = initCl.getDeclaredConstructor();
368 int mods = constructorToCall.getModifiers();
369 if ((mods & Modifier.PRIVATE) != 0 ||
370 ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
371 !packageEquals(cl, initCl))) {
372 return null;
373 }
374 } catch (NoSuchMethodException ex) {
375 return null;
376 }
|