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