blade.kit.ReflectKit Maven / Gradle / Ivy
/**
* Copyright (c) 2015, biezhi 王爵 ([email protected])
*
* 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 blade.kit;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import blade.kit.log.Logger;
/**
* 有关 Reflection处理的工具类。
*
* 这个类中的每个方法都可以“安全”地处理 null
,而不会抛出 NullPointerException
。
*
* @author biezhi
* @since 1.0
*/
public abstract class ReflectKit {
private static final Logger LOGGER = Logger.getLogger(ReflectKit.class);
/** 新建对象
* @throws IllegalAccessException
* @throws InstantiationException
* @throws ClassNotFoundException */
public static Object newInstance(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Object obj = null;
Class> clazz = Class.forName(className);
obj = clazz.newInstance();
LOGGER.debug("new %s", className);
return obj;
}
/**
* 创建一个实例对象
* @param clazz class对象
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static Object newInstance(Class> clazz) throws InstantiationException, IllegalAccessException{
return clazz.newInstance();
}
/** 用setter设置bean属性
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException */
public static void setProperty(Object bean, String name, Object value) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String methodName = "set" + StringKit.firstUpperCase(name);
invokeMehodByName(bean, methodName, value);
}
/** 用getter获取bean属性
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException */
public static Object getProperty(Object bean, String name) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String methodName = "get" + StringKit.firstUpperCase(name);
return invokeMehodByName(bean, methodName);
}
/** 类型转换 */
@SuppressWarnings("unchecked")
public static T cast(Object value, Class type) {
if (value != null && !type.isAssignableFrom(value.getClass())) {
if (is(type, int.class, Integer.class)) {
value = Integer.parseInt(String.valueOf(value));
} else if (is(type, long.class, Long.class)) {
value = Long.parseLong(String.valueOf(value));
} else if (is(type, float.class, Float.class)) {
value = Float.parseFloat(String.valueOf(value));
} else if (is(type, double.class, Double.class)) {
value = Double.parseDouble(String.valueOf(value));
} else if (is(type, boolean.class, Boolean.class)) {
value = Boolean.parseBoolean(String.valueOf(value));
} else if (is(type, String.class)) {
value = String.valueOf(value);
}
}
return (T) value;
}
/** 查找方法 */
public static Method getMethodByName(Object classOrBean, String methodName) {
Method ret = null;
if (classOrBean != null) {
Class> clazz = null;
if (classOrBean instanceof Class>) {
clazz = (Class>) classOrBean;
} else {
clazz = classOrBean.getClass();
}
for (Method method : clazz.getMethods()) {
if (method.getName().equals(methodName)) {
ret = method;
break;
}
}
}
return ret;
}
public static Method getMethodByName(Class> clazz, String methodName) {
Method ret = null;
for (Method method : clazz.getMethods()) {
if (method.getName().equals(methodName)) {
ret = method;
break;
}
}
return ret;
}
/**
*
* @param bean 类实例
* @param methodName 方法名称
* @param args 方法参数
* @return
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public static Object invokeMehodByName(Object bean, String methodName, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method method = getMethodByName(bean, methodName);
Class>[] types = method.getParameterTypes();
int argCount = args == null ? 0 : args.length;
// 参数个数对不上
ExceptionKit.makeRunTimeWhen(argCount != types.length,
"%s in %s", methodName, bean);
// 转参数类型
for (int i = 0; i < argCount; i++) {
args[i] = cast(args[i], types[i]);
}
return method.invoke(bean, args);
}
/**
*
* @param bean 类实例
* @param methodName 方法名称
* @param args 方法参数
* @return
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public static Object invokeMehod(Object bean, Method method, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class>[] types = method.getParameterTypes();
int argCount = args == null ? 0 : args.length;
// 参数个数对不上
ExceptionKit.makeRunTimeWhen(argCount != types.length, "%s in %s", method.getName(), bean);
// 转参数类型
for (int i = 0; i < argCount; i++) {
args[i] = cast(args[i], types[i]);
}
return method.invoke(bean, args);
}
// ------------------------------------------------------
/** 对象是否其中一个 */
public static boolean is(Object obj, Object... mybe) {
if (obj != null && mybe != null) {
for (Object mb : mybe)
if (obj.equals(mb))
return true;
}
return false;
}
public static boolean isNot(Object obj, Object... mybe) {
return !is(obj, mybe);
}
// ------------------------------------------------------
/** 扫描包下面所有的类 */
public static List scanPackageClass(String rootPackageName) {
List classNames = new ArrayList();
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL url = loader.getResource(rootPackageName.replace('.', '/'));
ExceptionKit.makeRunTimeWhen(url == null,
"package[%s] not found!", rootPackageName);
String protocol = url.getProtocol();
if ("file".equals(protocol)) {
LOGGER.debug("scan in file");
File[] files = new File(url.toURI()).listFiles();
for (File f : files) {
scanPackageClassInFile(rootPackageName, f, classNames);
}
} else if ("jar".equals(protocol)) {
LOGGER.debug("scan in jar");
JarFile jar = ((JarURLConnection) url.openConnection())
.getJarFile();
scanPackageClassInJar(jar, rootPackageName, classNames);
}
} catch (URISyntaxException e) {
} catch (IOException e) {
}
return classNames;
}
/** 扫描文件夹下所有class文件 */
private static void scanPackageClassInFile(String rootPackageName,
File rootFile, List classNames) {
String absFileName = rootPackageName + "." + rootFile.getName();
if (rootFile.isFile() && absFileName.endsWith(".class")) {
classNames.add(absFileName.substring(0, absFileName.length() - 6));
} else if (rootFile.isDirectory()) {
String tmPackageName = rootPackageName + "." + rootFile.getName();
for (File f : rootFile.listFiles()) {
scanPackageClassInFile(tmPackageName, f, classNames);
}
}
}
/**
* 扫描jar里面的类
* @param jar jar包文件
* @param packageDirName 包目录
* @param classNames class名称列表
*/
private static void scanPackageClassInJar(JarFile jar, String packageDirName, List classNames) {
Enumeration entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName().replace('/', '.');
if (name.startsWith(packageDirName) && name.endsWith(".class")) {
classNames.add(name.substring(0, name.length() - 6));
}
}
}
/**
* 方法调用,如果clazz
为null
,返回null
;
*
* 如果method
为null
,返回null
*
* 如果target
为null
,则为静态方法
*
* @param method 调用的方法
* @param target 目标对象
* @param args 方法的参数值
* @return 调用结果
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public static Object invokeMethod(Method method, Object target, Object...args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (method == null) {
return null;
}
method.setAccessible(true);
return method.invoke(target, args);
}
/**
*
* 调用一个命名的方法,其参数类型相匹配的对象类型。
*
*
*
* @param object 调用方法作用的对象
* @param methodName 方法名
* @param args 参数值
* @param parameterTypes 参数类型
* @return 调用的方法的返回值
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*
*/
public static Object invokeMethod(Object object, String methodName, Object[] args, Class>...parameterTypes) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (object == null || StringKit.isEmpty(methodName)) {
return null;
}
if (parameterTypes == null) {
parameterTypes = Emptys.EMPTY_CLASS_ARRAY;
}
if (args == null) {
args = Emptys.EMPTY_OBJECT_ARRAY;
}
Method method;
try {
method = object.getClass().getDeclaredMethod(methodName, parameterTypes);
} catch (Exception ex) {
throw ExceptionKit.toRuntimeException(ex);
}
if (method == null) {
return null;
}
return invokeMethod(method, object, args);
}
/**
*
* 调用一个命名的静态方法,其参数类型相匹配的对象类型。
*
*
*
* @param clazz 调用方法作用的类
* @param methodName 方法名
* @param args 参数值
* @param parameterTypes 参数类型
* @return 调用的方法的返回值
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*
*/
public static Object invokeStaticMethod(Class> clazz, String methodName, Object[] args, Class>...parameterTypes) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (parameterTypes == null) {
parameterTypes = Emptys.EMPTY_CLASS_ARRAY;
}
if (args == null) {
args = Emptys.EMPTY_OBJECT_ARRAY;
}
Method method;
try {
method = clazz.getDeclaredMethod(methodName, parameterTypes);
} catch (Exception ex) {
throw ExceptionKit.toRuntimeException(ex);
}
if (method == null) {
return null;
}
return invokeMethod(method, null, args);
}
// ==========================================================================
// 辅助方法。
// ==========================================================================
private static final Method IS_SYNTHETIC;
static {
Method isSynthetic = null;
if (SystemKit.getJavaInfo().isJavaVersionAtLeast(1.5f)) {
// cannot call synthetic methods:
try {
isSynthetic = Member.class.getMethod("isSynthetic", Emptys.EMPTY_CLASS_ARRAY);
} catch (Exception e) {
// ignore
}
}
IS_SYNTHETIC = isSynthetic;
}
public static boolean isAccessible(Member m) {
return m != null && Modifier.isPublic(m.getModifiers()) && !isSynthetic(m);
}
static boolean isSynthetic(Member m) {
if (IS_SYNTHETIC != null) {
try {
return ((Boolean) IS_SYNTHETIC.invoke(m, (Object[]) null)).booleanValue();
} catch (Exception e) {
}
}
return false;
}
/**
* Check whether the {@link Class} identified by the supplied name is present.
*
* @param className the name of the class to check
* @return true if class is present, false otherwise
*/
public static boolean isPresent(String className) {
try {
// what's wrong with old plain Class.forName
// this code supposed to work everywhere including containers
Class.forName(className);
// getClassLoader().loadClass(className);
return true;
}
catch (Throwable ex) {
return false;
}
}
public static boolean isPublic(Member m) {
return m != null && Modifier.isPublic(m.getModifiers());
}
public static void forceAccess(AccessibleObject object) {
if (object == null || object.isAccessible()) {
return;
}
try {
object.setAccessible(true);
} catch (SecurityException e) {
throw ExceptionKit.toRuntimeException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy