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 }
|