首页

类反向映射工具类ReflectUtil(实现对象属性查询修改克隆)

标签:Field,reflect,反向映射,字段属性重定义,工具类,java,ReflectionUtils,spring     发布时间:2016-07-22   

1.自定义工具类 - 通过该工具类实现对象属性的修改、属性名称获取值、深度克隆属性的内容,使用业务抽象层面的初始化改造、遍历修改或动态修改任意类属性等场景,具体代码示例如下

import java.lang.reflect.Field;@b@import java.math.BigDecimal;@b@import java.util.Date;@b@import com.xwood.common.util.DateUtils;@b@@b@public class ReflectUtil {@b@	/**@b@	 * 获取类的字段值@b@	 * @param source 类的对象@b@	 * @param fieldName 字段名称@b@	 * @return	@b@	 * @throws NoSuchFieldException @b@	 */@b@	public static Object getFieldValue(Object source,String fieldName) throws NoSuchFieldException@b@	{@b@		Object o = null;@b@		try {@b@			Field field = source.getClass().getDeclaredField(fieldName);@b@			field.setAccessible(true);@b@			o = field.get(source);@b@		} catch (SecurityException e) {@b@			e.printStackTrace();@b@		} catch (NoSuchFieldException e) {@b@			throw e;@b@		} catch (IllegalArgumentException e) {@b@			e.printStackTrace();@b@		} catch (IllegalAccessException e) {@b@			e.printStackTrace();@b@		}@b@		return o;@b@	}@b@	@b@	/**@b@	 * 设置字段值@b@	 * @param source@b@	 * @param fieldName@b@	 * @param fieldvalue@b@	 * @throws NoSuchFieldException @b@	 */@b@	public static void setFiledValue(Object source,String fieldName,Object fieldvalue) throws NoSuchFieldException@b@	{@b@		try {@b@			Field field = source.getClass().getDeclaredField(fieldName);@b@			field.setAccessible(true);@b@			setValue(source, field, fieldvalue);@b@		} catch (SecurityException e) {@b@			e.printStackTrace();@b@		} catch (NoSuchFieldException e) {@b@			throw e;@b@		} catch (IllegalArgumentException e) {@b@			e.printStackTrace();@b@		} catch (IllegalAccessException e) {@b@			e.printStackTrace();@b@		}@b@	}@b@	@b@	/**@b@	 * @see ObjectConvertorUtils@b@	 */@b@	private static void setValue(Object obj, Field field, Object value) throws IllegalAccessException{@b@		if(value == null){@b@			return;@b@		}@b@		try{@b@			field.set(obj, value);@b@		}catch(IllegalArgumentException e){@b@			field.set(obj, getRealValue(field.getType(),value));@b@		}@b@	}@b@	@b@	private static Object getRealValue(Class<?> type, Object value){@b@		if(int.class.isAssignableFrom(type)){@b@			return new Integer(value.toString());@b@		}else if (Integer.class.isAssignableFrom(type)) {@b@			return new Integer(value.toString());@b@		}else if(long.class.isAssignableFrom(type)){@b@			return new Long(value.toString());@b@		}else if(boolean.class.isAssignableFrom(type)){@b@			return new Boolean(value.toString());@b@		}else if(double.class.isAssignableFrom(type)){@b@			return new Double(value.toString());@b@		}else if(char.class.isAssignableFrom(type)){@b@			return (Character) value.toString().charAt(0);@b@		}else if(short.class.isAssignableFrom(type)){@b@			return new Short(value.toString());@b@		}else if(float.class.isAssignableFrom(type)){@b@			return new Float(value.toString());@b@		}else if(byte.class.isAssignableFrom(type)){@b@			return new Byte(value.toString());@b@		}else if(BigDecimal.class.isAssignableFrom(type)){@b@			return new BigDecimal(value.toString());@b@		}@b@		if(Date.class.isAssignableFrom(type)){@b@			return DateUtils.string2Date(value.toString());@b@		}@b@		return null;@b@	}@b@}

2.基于spring的org.springframework.util.ReflectionUtils类,源码如下

import java.lang.reflect.Constructor;@b@import java.lang.reflect.Field;@b@import java.lang.reflect.InvocationTargetException;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.Modifier;@b@import java.lang.reflect.UndeclaredThrowableException;@b@import java.sql.SQLException;@b@import java.util.ArrayList;@b@import java.util.Arrays;@b@import java.util.List;@b@import java.util.regex.Pattern;@b@@b@/**@b@ * Simple utility class for working with the reflection API and handling@b@ * reflection exceptions.@b@ *@b@ * <p>Only intended for internal use.@b@ *@b@ * @author Juergen Hoeller@b@ * @author Rob Harrop@b@ * @author Rod Johnson@b@ * @author Costin Leau@b@ * @author Sam Brannen@b@ * @author Chris Beams@b@ * @since 1.2.2@b@ */@b@public abstract class ReflectionUtils {@b@@b@	private static final Pattern CGLIB_RENAMED_METHOD_PATTERN = Pattern.compile("CGLIB\\$(.+)\\$\\d+");@b@@b@	/**@b@	 * Attempt to find a {@link Field field} on the supplied {@link Class} with the@b@	 * supplied <code>name</code>. Searches all superclasses up to {@link Object}.@b@	 * @param clazz the class to introspect@b@	 * @param name the name of the field@b@	 * @return the corresponding Field object, or <code>null</code> if not found@b@	 */@b@	public static Field findField(Class<?> clazz, String name) {@b@		return findField(clazz, name, null);@b@	}@b@@b@	/**@b@	 * Attempt to find a {@link Field field} on the supplied {@link Class} with the@b@	 * supplied <code>name</code> and/or {@link Class type}. Searches all superclasses@b@	 * up to {@link Object}.@b@	 * @param clazz the class to introspect@b@	 * @param name the name of the field (may be <code>null</code> if type is specified)@b@	 * @param type the type of the field (may be <code>null</code> if name is specified)@b@	 * @return the corresponding Field object, or <code>null</code> if not found@b@	 */@b@	public static Field findField(Class<?> clazz, String name, Class<?> type) {@b@		Assert.notNull(clazz, "Class must not be null");@b@		Assert.isTrue(name != null || type != null, "Either name or type of the field must be specified");@b@		Class<?> searchType = clazz;@b@		while (!Object.class.equals(searchType) && searchType != null) {@b@			Field[] fields = searchType.getDeclaredFields();@b@			for (Field field : fields) {@b@				if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) {@b@					return field;@b@				}@b@			}@b@			searchType = searchType.getSuperclass();@b@		}@b@		return null;@b@	}@b@@b@	/**@b@	 * Set the field represented by the supplied {@link Field field object} on the@b@	 * specified {@link Object target object} to the specified <code>value</code>.@b@	 * In accordance with {@link Field#set(Object, Object)} semantics, the new value@b@	 * is automatically unwrapped if the underlying field has a primitive type.@b@	 * <p>Thrown exceptions are handled via a call to {@link #handleReflectionException(Exception)}.@b@	 * @param field the field to set@b@	 * @param target the target object on which to set the field@b@	 * @param value the value to set; may be <code>null</code>@b@	 */@b@	public static void setField(Field field, Object target, Object value) {@b@		try {@b@			field.set(target, value);@b@		}@b@		catch (IllegalAccessException ex) {@b@			handleReflectionException(ex);@b@			throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": "@b@					+ ex.getMessage());@b@		}@b@	}@b@@b@	/**@b@	 * Get the field represented by the supplied {@link Field field object} on the@b@	 * specified {@link Object target object}. In accordance with {@link Field#get(Object)}@b@	 * semantics, the returned value is automatically wrapped if the underlying field@b@	 * has a primitive type.@b@	 * <p>Thrown exceptions are handled via a call to {@link #handleReflectionException(Exception)}.@b@	 * @param field the field to get@b@	 * @param target the target object from which to get the field@b@	 * @return the field's current value@b@	 */@b@	public static Object getField(Field field, Object target) {@b@		try {@b@			return field.get(target);@b@		}@b@		catch (IllegalAccessException ex) {@b@			handleReflectionException(ex);@b@			throw new IllegalStateException(@b@					"Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage());@b@		}@b@	}@b@@b@	/**@b@	 * Attempt to find a {@link Method} on the supplied class with the supplied name@b@	 * and no parameters. Searches all superclasses up to <code>Object</code>.@b@	 * <p>Returns <code>null</code> if no {@link Method} can be found.@b@	 * @param clazz the class to introspect@b@	 * @param name the name of the method@b@	 * @return the Method object, or <code>null</code> if none found@b@	 */@b@	public static Method findMethod(Class<?> clazz, String name) {@b@		return findMethod(clazz, name, new Class[0]);@b@	}@b@@b@	/**@b@	 * Attempt to find a {@link Method} on the supplied class with the supplied name@b@	 * and parameter types. Searches all superclasses up to <code>Object</code>.@b@	 * <p>Returns <code>null</code> if no {@link Method} can be found.@b@	 * @param clazz the class to introspect@b@	 * @param name the name of the method@b@	 * @param paramTypes the parameter types of the method@b@	 * (may be <code>null</code> to indicate any signature)@b@	 * @return the Method object, or <code>null</code> if none found@b@	 */@b@	public static Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes) {@b@		Assert.notNull(clazz, "Class must not be null");@b@		Assert.notNull(name, "Method name must not be null");@b@		Class<?> searchType = clazz;@b@		while (searchType != null) {@b@			Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods());@b@			for (Method method : methods) {@b@				if (name.equals(method.getName())@b@						&& (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) {@b@					return method;@b@				}@b@			}@b@			searchType = searchType.getSuperclass();@b@		}@b@		return null;@b@	}@b@@b@	/**@b@	 * Invoke the specified {@link Method} against the supplied target object with no arguments.@b@	 * The target object can be <code>null</code> when invoking a static {@link Method}.@b@	 * <p>Thrown exceptions are handled via a call to {@link #handleReflectionException}.@b@	 * @param method the method to invoke@b@	 * @param target the target object to invoke the method on@b@	 * @return the invocation result, if any@b@	 * @see #invokeMethod(java.lang.reflect.Method, Object, Object[])@b@	 */@b@	public static Object invokeMethod(Method method, Object target) {@b@		return invokeMethod(method, target, new Object[0]);@b@	}@b@@b@	/**@b@	 * Invoke the specified {@link Method} against the supplied target object with the@b@	 * supplied arguments. The target object can be <code>null</code> when invoking a@b@	 * static {@link Method}.@b@	 * <p>Thrown exceptions are handled via a call to {@link #handleReflectionException}.@b@	 * @param method the method to invoke@b@	 * @param target the target object to invoke the method on@b@	 * @param args the invocation arguments (may be <code>null</code>)@b@	 * @return the invocation result, if any@b@	 */@b@	public static Object invokeMethod(Method method, Object target, Object... args) {@b@		try {@b@			return method.invoke(target, args);@b@		}@b@		catch (Exception ex) {@b@			handleReflectionException(ex);@b@		}@b@		throw new IllegalStateException("Should never get here");@b@	}@b@@b@	/**@b@	 * Invoke the specified JDBC API {@link Method} against the supplied target@b@	 * object with no arguments.@b@	 * @param method the method to invoke@b@	 * @param target the target object to invoke the method on@b@	 * @return the invocation result, if any@b@	 * @throws SQLException the JDBC API SQLException to rethrow (if any)@b@	 * @see #invokeJdbcMethod(java.lang.reflect.Method, Object, Object[])@b@	 */@b@	public static Object invokeJdbcMethod(Method method, Object target) throws SQLException {@b@		return invokeJdbcMethod(method, target, new Object[0]);@b@	}@b@@b@	/**@b@	 * Invoke the specified JDBC API {@link Method} against the supplied target@b@	 * object with the supplied arguments.@b@	 * @param method the method to invoke@b@	 * @param target the target object to invoke the method on@b@	 * @param args the invocation arguments (may be <code>null</code>)@b@	 * @return the invocation result, if any@b@	 * @throws SQLException the JDBC API SQLException to rethrow (if any)@b@	 * @see #invokeMethod(java.lang.reflect.Method, Object, Object[])@b@	 */@b@	public static Object invokeJdbcMethod(Method method, Object target, Object... args) throws SQLException {@b@		try {@b@			return method.invoke(target, args);@b@		}@b@		catch (IllegalAccessException ex) {@b@			handleReflectionException(ex);@b@		}@b@		catch (InvocationTargetException ex) {@b@			if (ex.getTargetException() instanceof SQLException) {@b@				throw (SQLException) ex.getTargetException();@b@			}@b@			handleInvocationTargetException(ex);@b@		}@b@		throw new IllegalStateException("Should never get here");@b@	}@b@@b@	/**@b@	 * Handle the given reflection exception. Should only be called if no@b@	 * checked exception is expected to be thrown by the target method.@b@	 * <p>Throws the underlying RuntimeException or Error in case of an@b@	 * InvocationTargetException with such a root cause. Throws an@b@	 * IllegalStateException with an appropriate message else.@b@	 * @param ex the reflection exception to handle@b@	 */@b@	public static void handleReflectionException(Exception ex) {@b@		if (ex instanceof NoSuchMethodException) {@b@			throw new IllegalStateException("Method not found: " + ex.getMessage());@b@		}@b@		if (ex instanceof IllegalAccessException) {@b@			throw new IllegalStateException("Could not access method: " + ex.getMessage());@b@		}@b@		if (ex instanceof InvocationTargetException) {@b@			handleInvocationTargetException((InvocationTargetException) ex);@b@		}@b@		if (ex instanceof RuntimeException) {@b@			throw (RuntimeException) ex;@b@		}@b@		throw new UndeclaredThrowableException(ex);@b@	}@b@@b@	/**@b@	 * Handle the given invocation target exception. Should only be called if no@b@	 * checked exception is expected to be thrown by the target method.@b@	 * <p>Throws the underlying RuntimeException or Error in case of such a root@b@	 * cause. Throws an IllegalStateException else.@b@	 * @param ex the invocation target exception to handle@b@	 */@b@	public static void handleInvocationTargetException(InvocationTargetException ex) {@b@		rethrowRuntimeException(ex.getTargetException());@b@	}@b@@b@	/**@b@	 * Rethrow the given {@link Throwable exception}, which is presumably the@b@	 * <em>target exception</em> of an {@link InvocationTargetException}. Should@b@	 * only be called if no checked exception is expected to be thrown by the@b@	 * target method.@b@	 * <p>Rethrows the underlying exception cast to an {@link RuntimeException} or@b@	 * {@link Error} if appropriate; otherwise, throws an@b@	 * {@link IllegalStateException}.@b@	 * @param ex the exception to rethrow@b@	 * @throws RuntimeException the rethrown exception@b@	 */@b@	public static void rethrowRuntimeException(Throwable ex) {@b@		if (ex instanceof RuntimeException) {@b@			throw (RuntimeException) ex;@b@		}@b@		if (ex instanceof Error) {@b@			throw (Error) ex;@b@		}@b@		throw new UndeclaredThrowableException(ex);@b@	}@b@@b@	/**@b@	 * Rethrow the given {@link Throwable exception}, which is presumably the@b@	 * <em>target exception</em> of an {@link InvocationTargetException}. Should@b@	 * only be called if no checked exception is expected to be thrown by the@b@	 * target method.@b@	 * <p>Rethrows the underlying exception cast to an {@link Exception} or@b@	 * {@link Error} if appropriate; otherwise, throws an@b@	 * {@link IllegalStateException}.@b@	 * @param ex the exception to rethrow@b@	 * @throws Exception the rethrown exception (in case of a checked exception)@b@	 */@b@	public static void rethrowException(Throwable ex) throws Exception {@b@		if (ex instanceof Exception) {@b@			throw (Exception) ex;@b@		}@b@		if (ex instanceof Error) {@b@			throw (Error) ex;@b@		}@b@		throw new UndeclaredThrowableException(ex);@b@	}@b@@b@	/**@b@	 * Determine whether the given method explicitly declares the given@b@	 * exception or one of its superclasses, which means that an exception of@b@	 * that type can be propagated as-is within a reflective invocation.@b@	 * @param method the declaring method@b@	 * @param exceptionType the exception to throw@b@	 * @return <code>true</code> if the exception can be thrown as-is;@b@	 * <code>false</code> if it needs to be wrapped@b@	 */@b@	public static boolean declaresException(Method method, Class<?> exceptionType) {@b@		Assert.notNull(method, "Method must not be null");@b@		Class<?>[] declaredExceptions = method.getExceptionTypes();@b@		for (Class<?> declaredException : declaredExceptions) {@b@			if (declaredException.isAssignableFrom(exceptionType)) {@b@				return true;@b@			}@b@		}@b@		return false;@b@	}@b@@b@	/**@b@	 * Determine whether the given field is a "public static final" constant.@b@	 * @param field the field to check@b@	 */@b@	public static boolean isPublicStaticFinal(Field field) {@b@		int modifiers = field.getModifiers();@b@		return (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers));@b@	}@b@@b@	/**@b@	 * Determine whether the given method is an "equals" method.@b@	 * @see java.lang.Object#equals(Object)@b@	 */@b@	public static boolean isEqualsMethod(Method method) {@b@		if (method == null || !method.getName().equals("equals")) {@b@			return false;@b@		}@b@		Class<?>[] paramTypes = method.getParameterTypes();@b@		return (paramTypes.length == 1 && paramTypes[0] == Object.class);@b@	}@b@@b@	/**@b@	 * Determine whether the given method is a "hashCode" method.@b@	 * @see java.lang.Object#hashCode()@b@	 */@b@	public static boolean isHashCodeMethod(Method method) {@b@		return (method != null && method.getName().equals("hashCode") && method.getParameterTypes().length == 0);@b@	}@b@@b@	/**@b@	 * Determine whether the given method is a "toString" method.@b@	 * @see java.lang.Object#toString()@b@	 */@b@	public static boolean isToStringMethod(Method method) {@b@		return (method != null && method.getName().equals("toString") && method.getParameterTypes().length == 0);@b@	}@b@@b@	/**@b@	 * Determine whether the given method is originally declared by {@link java.lang.Object}.@b@	 */@b@	public static boolean isObjectMethod(Method method) {@b@		try {@b@			Object.class.getDeclaredMethod(method.getName(), method.getParameterTypes());@b@			return true;@b@		} catch (SecurityException ex) {@b@			return false;@b@		} catch (NoSuchMethodException ex) {@b@			return false;@b@		}@b@	}@b@@b@	/**@b@	 * Determine whether the given method is a CGLIB 'renamed' method, following@b@	 * the pattern "CGLIB$methodName$0".@b@	 * @param renamedMethod the method to check@b@	 * @see org.springframework.cglib.proxy.Enhancer#rename@b@	 */@b@	public static boolean isCglibRenamedMethod(Method renamedMethod) {@b@		return CGLIB_RENAMED_METHOD_PATTERN.matcher(renamedMethod.getName()).matches();@b@	}@b@@b@	/**@b@	 * Make the given field accessible, explicitly setting it accessible if@b@	 * necessary. The <code>setAccessible(true)</code> method is only called@b@	 * when actually necessary, to avoid unnecessary conflicts with a JVM@b@	 * SecurityManager (if active).@b@	 * @param field the field to make accessible@b@	 * @see java.lang.reflect.Field#setAccessible@b@	 */@b@	public static void makeAccessible(Field field) {@b@		if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) ||@b@				Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {@b@			field.setAccessible(true);@b@		}@b@	}@b@@b@	/**@b@	 * Make the given method accessible, explicitly setting it accessible if@b@	 * necessary. The <code>setAccessible(true)</code> method is only called@b@	 * when actually necessary, to avoid unnecessary conflicts with a JVM@b@	 * SecurityManager (if active).@b@	 * @param method the method to make accessible@b@	 * @see java.lang.reflect.Method#setAccessible@b@	 */@b@	public static void makeAccessible(Method method) {@b@		if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))@b@				&& !method.isAccessible()) {@b@			method.setAccessible(true);@b@		}@b@	}@b@@b@	/**@b@	 * Make the given constructor accessible, explicitly setting it accessible@b@	 * if necessary. The <code>setAccessible(true)</code> method is only called@b@	 * when actually necessary, to avoid unnecessary conflicts with a JVM@b@	 * SecurityManager (if active).@b@	 * @param ctor the constructor to make accessible@b@	 * @see java.lang.reflect.Constructor#setAccessible@b@	 */@b@	public static void makeAccessible(Constructor<?> ctor) {@b@		if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers()))@b@				&& !ctor.isAccessible()) {@b@			ctor.setAccessible(true);@b@		}@b@	}@b@@b@	/**@b@	 * Perform the given callback operation on all matching methods of the given@b@	 * class and superclasses.@b@	 * <p>The same named method occurring on subclass and superclass will appear@b@	 * twice, unless excluded by a {@link MethodFilter}.@b@	 * @param clazz class to start looking at@b@	 * @param mc the callback to invoke for each method@b@	 * @see #doWithMethods(Class, MethodCallback, MethodFilter)@b@	 */@b@	public static void doWithMethods(Class<?> clazz, MethodCallback mc) throws IllegalArgumentException {@b@		doWithMethods(clazz, mc, null);@b@	}@b@@b@	/**@b@	 * Perform the given callback operation on all matching methods of the given@b@	 * class and superclasses (or given interface and super-interfaces).@b@	 * <p>The same named method occurring on subclass and superclass will appear@b@	 * twice, unless excluded by the specified {@link MethodFilter}.@b@	 * @param clazz class to start looking at@b@	 * @param mc the callback to invoke for each method@b@	 * @param mf the filter that determines the methods to apply the callback to@b@	 */@b@	public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf)@b@			throws IllegalArgumentException {@b@@b@		// Keep backing up the inheritance hierarchy.@b@		Method[] methods = clazz.getDeclaredMethods();@b@		for (Method method : methods) {@b@			if (mf != null && !mf.matches(method)) {@b@				continue;@b@			}@b@			try {@b@				mc.doWith(method);@b@			}@b@			catch (IllegalAccessException ex) {@b@				throw new IllegalStateException("Shouldn't be illegal to access method '" + method.getName()@b@						+ "': " + ex);@b@			}@b@		}@b@		if (clazz.getSuperclass() != null) {@b@			doWithMethods(clazz.getSuperclass(), mc, mf);@b@		}@b@		else if (clazz.isInterface()) {@b@			for (Class<?> superIfc : clazz.getInterfaces()) {@b@				doWithMethods(superIfc, mc, mf);@b@			}@b@		}@b@	}@b@@b@	/**@b@	 * Get all declared methods on the leaf class and all superclasses. Leaf@b@	 * class methods are included first.@b@	 */@b@	public static Method[] getAllDeclaredMethods(Class<?> leafClass) throws IllegalArgumentException {@b@		final List<Method> methods = new ArrayList<Method>(32);@b@		doWithMethods(leafClass, new MethodCallback() {@b@			public void doWith(Method method) {@b@				methods.add(method);@b@			}@b@		});@b@		return methods.toArray(new Method[methods.size()]);@b@	}@b@@b@	/**@b@	 * Get the unique set of declared methods on the leaf class and all superclasses. Leaf@b@	 * class methods are included first and while traversing the superclass hierarchy any methods found@b@	 * with signatures matching a method already included are filtered out.@b@	 */@b@	public static Method[] getUniqueDeclaredMethods(Class<?> leafClass) throws IllegalArgumentException {@b@		final List<Method> methods = new ArrayList<Method>(32);@b@		doWithMethods(leafClass, new MethodCallback() {@b@			public void doWith(Method method) {@b@				boolean knownSignature = false;@b@				Method methodBeingOverriddenWithCovariantReturnType = null;@b@@b@				for (Method existingMethod : methods) {@b@					if (method.getName().equals(existingMethod.getName()) &&@b@							Arrays.equals(method.getParameterTypes(), existingMethod.getParameterTypes())) {@b@						// is this a covariant return type situation?@b@						if (existingMethod.getReturnType() != method.getReturnType() &&@b@								existingMethod.getReturnType().isAssignableFrom(method.getReturnType())) {@b@							methodBeingOverriddenWithCovariantReturnType = existingMethod;@b@						} else {@b@							knownSignature = true;@b@						}@b@						break;@b@					}@b@				}@b@				if (methodBeingOverriddenWithCovariantReturnType != null) {@b@					methods.remove(methodBeingOverriddenWithCovariantReturnType);@b@				}@b@				if (!knownSignature && !isCglibRenamedMethod(method)) {@b@					methods.add(method);@b@				}@b@			}@b@		});@b@		return methods.toArray(new Method[methods.size()]);@b@	}@b@@b@	/**@b@	 * Invoke the given callback on all fields in the target class, going up the@b@	 * class hierarchy to get all declared fields.@b@	 * @param clazz the target class to analyze@b@	 * @param fc the callback to invoke for each field@b@	 */@b@	public static void doWithFields(Class<?> clazz, FieldCallback fc) throws IllegalArgumentException {@b@		doWithFields(clazz, fc, null);@b@	}@b@@b@	/**@b@	 * Invoke the given callback on all fields in the target class, going up the@b@	 * class hierarchy to get all declared fields.@b@	 * @param clazz the target class to analyze@b@	 * @param fc the callback to invoke for each field@b@	 * @param ff the filter that determines the fields to apply the callback to@b@	 */@b@	public static void doWithFields(Class<?> clazz, FieldCallback fc, FieldFilter ff)@b@			throws IllegalArgumentException {@b@@b@		// Keep backing up the inheritance hierarchy.@b@		Class<?> targetClass = clazz;@b@		do {@b@			Field[] fields = targetClass.getDeclaredFields();@b@			for (Field field : fields) {@b@				// Skip static and final fields.@b@				if (ff != null && !ff.matches(field)) {@b@					continue;@b@				}@b@				try {@b@					fc.doWith(field);@b@				}@b@				catch (IllegalAccessException ex) {@b@					throw new IllegalStateException(@b@							"Shouldn't be illegal to access field '" + field.getName() + "': " + ex);@b@				}@b@			}@b@			targetClass = targetClass.getSuperclass();@b@		}@b@		while (targetClass != null && targetClass != Object.class);@b@	}@b@@b@	/**@b@	 * Given the source object and the destination, which must be the same class@b@	 * or a subclass, copy all fields, including inherited fields. Designed to@b@	 * work on objects with public no-arg constructors.@b@	 * @throws IllegalArgumentException if the arguments are incompatible@b@	 */@b@	public static void shallowCopyFieldState(final Object src, final Object dest) throws IllegalArgumentException {@b@		if (src == null) {@b@			throw new IllegalArgumentException("Source for field copy cannot be null");@b@		}@b@		if (dest == null) {@b@			throw new IllegalArgumentException("Destination for field copy cannot be null");@b@		}@b@		if (!src.getClass().isAssignableFrom(dest.getClass())) {@b@			throw new IllegalArgumentException("Destination class [" + dest.getClass().getName()@b@					+ "] must be same or subclass as source class [" + src.getClass().getName() + "]");@b@		}@b@		doWithFields(src.getClass(), new FieldCallback() {@b@			public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {@b@				makeAccessible(field);@b@				Object srcValue = field.get(src);@b@				field.set(dest, srcValue);@b@			}@b@		}, COPYABLE_FIELDS);@b@	}@b@@b@@b@	/**@b@	 * Action to take on each method.@b@	 */@b@	public interface MethodCallback {@b@@b@		/**@b@		 * Perform an operation using the given method.@b@		 * @param method the method to operate on@b@		 */@b@		void doWith(Method method) throws IllegalArgumentException, IllegalAccessException;@b@	}@b@@b@@b@	/**@b@	 * Callback optionally used to filter methods to be operated on by a method callback.@b@	 */@b@	public interface MethodFilter {@b@@b@		/**@b@		 * Determine whether the given method matches.@b@		 * @param method the method to check@b@		 */@b@		boolean matches(Method method);@b@	}@b@@b@@b@	/**@b@	 * Callback interface invoked on each field in the hierarchy.@b@	 */@b@	public interface FieldCallback {@b@@b@		/**@b@		 * Perform an operation using the given field.@b@		 * @param field the field to operate on@b@		 */@b@		void doWith(Field field) throws IllegalArgumentException, IllegalAccessException;@b@	}@b@@b@@b@	/**@b@	 * Callback optionally used to filter fields to be operated on by a field callback.@b@	 */@b@	public interface FieldFilter {@b@@b@		/**@b@		 * Determine whether the given field matches.@b@		 * @param field the field to check@b@		 */@b@		boolean matches(Field field);@b@	}@b@@b@@b@	/**@b@	 * Pre-built FieldFilter that matches all non-static, non-final fields.@b@	 */@b@	public static FieldFilter COPYABLE_FIELDS = new FieldFilter() {@b@@b@		public boolean matches(Field field) {@b@			return !(Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers()));@b@		}@b@	};@b@@b@@b@	/**@b@	 * Pre-built MethodFilter that matches all non-bridge methods.@b@	 */@b@	public static MethodFilter NON_BRIDGED_METHODS = new MethodFilter() {@b@@b@		public boolean matches(Method method) {@b@			return !method.isBridge();@b@		}@b@	};@b@@b@@b@	/**@b@	 * Pre-built MethodFilter that matches all non-bridge methods@b@	 * which are not declared on <code>java.lang.Object</code>.@b@	 */@b@	public static MethodFilter USER_DECLARED_METHODS = new MethodFilter() {@b@@b@		public boolean matches(Method method) {@b@			return (!method.isBridge() && method.getDeclaringClass() != Object.class);@b@		}@b@	};@b@@b@}

  

<<热门下载>>