private static <T> T getFieldInternal(Object instance, Class<?> fieldOwner, String fieldname) { Field target; try { target = fieldOwner.getDeclaredField(fieldname); } catch (NoSuchFieldException e) { throw Exceptions.newIllegalArgumentException("%s has no field named %s", instance, fieldname); } boolean alreadyAccessible = target.isAccessible(); if (!alreadyAccessible) { target.setAccessible(true); } try { @SuppressWarnings("unchecked") // we've already left statically-typed land, // so we may as well make it convenient for callers T value = (T) target.get(instance); return value; } catch (IllegalAccessException e) { throw Throwables.propagate(e); } finally { if (!alreadyAccessible) { target.setAccessible(false); } } }
public static <T> InvocationTarget<T> invokeSpecificMethod( Object instance, Class<?> methodOwner, String methodName, Class<?>... argTypes) { Preconditions.checkArgument( methodOwner.isInstance(instance), "%s is not a %s", instance, methodOwner); Method target; try { target = methodOwner.getDeclaredMethod(methodName, argTypes); } catch (NoSuchMethodException e) { throw Exceptions.newIllegalArgumentException( "%s has no method named %s and with argument types %s", instance.getClass(), methodName, Arrays.toString(argTypes)); } return new InvocationTarget<T>(target, instance); }
/** * Uses reflection to set a (potentially private) non-static field to the given value. * * @param instance the object instance whose private field should be changed * @param fieldOwner the class that declares the target field * @param fieldname the name of the target field * @param value the new value */ public static void setField( Object instance, Class<?> fieldOwner, String fieldname, Object value) { Preconditions.checkArgument( fieldOwner.isInstance(instance), "%s is not a %s", instance, fieldOwner); Field target; try { target = fieldOwner.getDeclaredField(fieldname); } catch (NoSuchFieldException e) { throw Exceptions.newIllegalArgumentException("%s has no field named %s", instance, fieldname); } boolean alreadyAccessible = target.isAccessible(); if (!alreadyAccessible) { target.setAccessible(true); } try { target.set(instance, value); } catch (IllegalAccessException e) { throw Throwables.propagate(e); } finally { if (!alreadyAccessible) { target.setAccessible(false); } } }