beanutils.java
来自「有关此类编程有心德的高手 希望能够多多给予指教」· Java 代码 · 共 515 行 · 第 1/2 页
JAVA
515 行
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Static convenience methods for JavaBeans: for instantiating beans,
* checking bean property types, copying bean properties, etc.
*
* <p>Mainly for use within the framework, but to some degree also
* useful for application classes.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Rob Harrop
*/
public abstract class BeanUtils {
/**
* Convenience method to instantiate a class using its no-arg constructor.
* As this method doesn't try to load classes by name, it should avoid
* class-loading issues.
* <p>Note that this method tries to set the constructor accessible
* if given a non-accessible (that is, non-public) constructor.
* @param clazz class to instantiate
* @return the new instance
* @throws BeanInstantiationException if the bean cannot be instantiated
*/
public static Object instantiateClass(Class clazz) throws BeanInstantiationException {
Assert.notNull(clazz, "Class must not be null");
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
return instantiateClass(clazz.getDeclaredConstructor((Class[]) null), null);
}
catch (NoSuchMethodException ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
/**
* Convenience method to instantiate a class using the given constructor.
* As this method doesn't try to load classes by name, it should avoid
* class-loading issues.
* <p>Note that this method tries to set the constructor accessible
* if given a non-accessible (that is, non-public) constructor.
* @param ctor the constructor to instantiate
* @param args the constructor arguments to apply
* @return the new instance
* @throws BeanInstantiationException if the bean cannot be instantiated
*/
public static Object instantiateClass(Constructor ctor, Object[] args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
if (!Modifier.isPublic(ctor.getModifiers()) ||
!Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) {
ctor.setAccessible(true);
}
return ctor.newInstance(args);
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(),
"Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(),
"Has the class definition changed? Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(),
"Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(),
"Constructor threw exception", ex.getTargetException());
}
}
/**
* Find a method with the given method name and the given parameter types,
* declared on the given class or one of its superclasses. Prefers public methods,
* but will return a protected, package access, or private method too.
* <p>Checks <code>Class.getMethod</code> first, falling back to
* <code>findDeclaredMethod</code>. This allows to find public methods
* without issues even in environments with restricted Java security settings.
* @param clazz the class to check
* @param methodName the name of the method to find
* @param paramTypes the parameter types of the method to find
* @return the Method object, or <code>null</code> if not found
* @see java.lang.Class#getMethod
* @see #findDeclaredMethod
*/
public static Method findMethod(Class clazz, String methodName, Class[] paramTypes) {
try {
return clazz.getMethod(methodName, paramTypes);
}
catch (NoSuchMethodException ex) {
return findDeclaredMethod(clazz, methodName, paramTypes);
}
}
/**
* Find a method with the given method name and the given parameter types,
* declared on the given class or one of its superclasses. Will return a public,
* protected, package access, or private method.
* <p>Checks <code>Class.getDeclaredMethod</code>, cascading upwards to all superclasses.
* @param clazz the class to check
* @param methodName the name of the method to find
* @param paramTypes the parameter types of the method to find
* @return the Method object, or <code>null</code> if not found
* @see java.lang.Class#getDeclaredMethod
*/
public static Method findDeclaredMethod(Class clazz, String methodName, Class[] paramTypes) {
try {
return clazz.getDeclaredMethod(methodName, paramTypes);
}
catch (NoSuchMethodException ex) {
if (clazz.getSuperclass() != null) {
return findDeclaredMethod(clazz.getSuperclass(), methodName, paramTypes);
}
return null;
}
}
/**
* Find a method with the given method name and minimal parameters (best case: none),
* declared on the given class or one of its superclasses. Prefers public methods,
* but will return a protected, package access, or private method too.
* <p>Checks <code>Class.getMethods</code> first, falling back to
* <code>findDeclaredMethodWithMinimalParameters</code>. This allows to find public
* methods without issues even in environments with restricted Java security settings.
* @param clazz the class to check
* @param methodName the name of the method to find
* @return the Method object, or <code>null</code> if not found
* @throws IllegalArgumentException if methods of the given name were found but
* could not be resolved to a unique method with minimal parameters
* @see java.lang.Class#getMethods
* @see #findDeclaredMethodWithMinimalParameters
*/
public static Method findMethodWithMinimalParameters(Class clazz, String methodName)
throws IllegalArgumentException {
Method targetMethod = doFindMethodWithMinimalParameters(clazz.getDeclaredMethods(), methodName);
if (targetMethod == null) {
return findDeclaredMethodWithMinimalParameters(clazz, methodName);
}
return targetMethod;
}
/**
* Find a method with the given method name and minimal parameters (best case: none),
* declared on the given class or one of its superclasses. Will return a public,
* protected, package access, or private method.
* <p>Checks <code>Class.getDeclaredMethods</code>, cascading upwards to all superclasses.
* @param clazz the class to check
* @param methodName the name of the method to find
* @return the Method object, or <code>null</code> if not found
* @throws IllegalArgumentException if methods of the given name were found but
* could not be resolved to a unique method with minimal parameters
* @see java.lang.Class#getDeclaredMethods
*/
public static Method findDeclaredMethodWithMinimalParameters(Class clazz, String methodName)
throws IllegalArgumentException {
Method targetMethod = doFindMethodWithMinimalParameters(clazz.getDeclaredMethods(), methodName);
if (targetMethod == null && clazz.getSuperclass() != null) {
return findDeclaredMethodWithMinimalParameters(clazz.getSuperclass(), methodName);
}
return targetMethod;
}
/**
* Find a method with the given method name and minimal parameters (best case: none)
* in the given list of methods.
* @param methods the methods to check
* @param methodName the name of the method to find
* @return the Method object, or <code>null</code> if not found
* @throws IllegalArgumentException if methods of the given name were found but
* could not be resolved to a unique method with minimal parameters
*/
private static Method doFindMethodWithMinimalParameters(Method[] methods, String methodName)
throws IllegalArgumentException {
Method targetMethod = null;
int numMethodsFoundWithCurrentMinimumArgs = 0;
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(methodName)) {
int numParams = methods[i].getParameterTypes().length;
if (targetMethod == null ||
numParams < targetMethod.getParameterTypes().length) {
targetMethod = methods[i];
numMethodsFoundWithCurrentMinimumArgs = 1;
}
else {
if (targetMethod.getParameterTypes().length == numParams) {
// Additional candidate with same length.
numMethodsFoundWithCurrentMinimumArgs++;
}
}
}
}
if (numMethodsFoundWithCurrentMinimumArgs > 1) {
throw new IllegalArgumentException("Cannot resolve method '" + methodName +
"' to a unique method. Attempted to resolve to overloaded method with " +
"the least number of parameters, but there were " +
numMethodsFoundWithCurrentMinimumArgs + " candidates.");
}
return targetMethod;
}
/**
* Parse a method signature in the form <code>methodName[([arg_list])]</code>,
* where <code>arg_list</code> is an optional, comma-separated list of fully-qualified
* type names, and attempts to resolve that signature against the supplied <code>Class</code>.
* <p>When not supplying an argument list (<code>methodName</code>) the method whose name
* matches and has the least number of parameters will be returned. When supplying an
* argument type list, only the method whose name and argument types match will be returned.
* <p>Note then that <code>methodName</code> and <code>methodName()</code> are <strong>not</strong>
* resolved in the same way. The signature <code>methodName</code> means the method called
* <code>methodName</code> with the least number of arguments, whereas <code>methodName()</code>
* means the method called <code>methodName</code> with exactly 0 arguments.
* <p>If no method can be found, then <code>null</code> is returned.
* @param signature the method signature as String representation
* @param clazz the class to resolve the method signature against
* @return the resolved Method
* @see #findMethod
* @see #findMethodWithMinimalParameters
*/
public static Method resolveSignature(String signature, Class clazz) {
Assert.hasText(signature, "'signature' must not be empty");
Assert.notNull(clazz, "Class must not be null");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?