package com.opslab.util; import org.apache.log4j.Logger; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * <h6>Description:<h6> * <p>Java Class与反射相关的一些工具类</p> */ public final class ClassUtil { /** * 获取类加载器 */ public static ClassLoader overridenClassLoader; public static ClassLoader getContextClassLoader() { return overridenClassLoader != null ? overridenClassLoader : Thread.currentThread().getContextClassLoader(); } private static Logger logger = Logger.getLogger(ClassUtil.class); /** * 获取指定类的全部属性字段 * * @param className 需要获取的类名 * @param extendsField 是否获取接口或父类中的公共属性 * @return 属性字段数组 */ public final static String[] getField(String className, boolean extendsField) { Class classz = loadClass(className); Field[] fields = classz.getFields(); Set<String> set = new HashSet<>(); if (fields != null) { for (Field f : fields) { set.add(f.getName()); } } if (extendsField) { Field[] fieldz = classz.getDeclaredFields(); if (fieldz != null) { for (Field f : fieldz) { set.add(f.getName()); } } } return set.toArray(new String[set.size()]); } /** * 获取类中的公共属性 * * @param className 需要获取的类名 * @param extendsField 是否获取接口或父类中的公共属性 * @return 属性字段数组 */ public final static String[] getPublicField(String className, boolean extendsField) { Class classz = loadClass(className); Set<String> set = new HashSet<>(); Field[] fields = classz.getDeclaredFields(); if (fields != null) { for (Field f : fields) { String modifier = Modifier.toString(f.getModifiers()); if (modifier.startsWith("public")) { set.add(f.getName()); } } } if (extendsField) { Field[] fieldz = classz.getFields(); if (fieldz != null) { for (Field f : fieldz) { set.add(f.getName()); } } } return set.toArray(new String[set.size()]); } /** * 获取类中定义的protected类型的属性字段 * * @param className 需要获取的类名 * @return protected类型的属性字段数组 */ public final static String[] getProtectedField(String className) { Class classz = loadClass(className); Set<String> set = new HashSet<>(); Field[] fields = classz.getDeclaredFields(); if (fields != null) { for (Field f : fields) { String modifier = Modifier.toString(f.getModifiers()); if (modifier.startsWith("protected")) { set.add(f.getName()); } } } return set.toArray(new String[set.size()]); } /** * 获取类中定义的private类型的属性字段 * * @param className 需要获取的类名 * @return private类型的属性字段数组 */ public final static String[] getPrivateField(String className) { Class classz = loadClass(className); Set<String> set = new HashSet<>(); Field[] fields = classz.getDeclaredFields(); if (fields != null) { for (Field f : fields) { String modifier = Modifier.toString(f.getModifiers()); if (modifier.startsWith("private")) { set.add(f.getName()); } } } return set.toArray(new String[set.size()]); } /** * 获取对象的全部public类型方法 * * @param className 需要获取的类名 * @param extendsMethod 是否获取继承来的方法 * @return 方法名数组 */ public final static String[] getPublicMethod(String className, boolean extendsMethod) { Class classz = loadClass(className); Method[] methods; if (extendsMethod) { methods = classz.getMethods(); } else { methods = classz.getDeclaredMethods(); } Set<String> set = new HashSet<>(); if (methods != null) { for (Method f : methods) { String modifier = Modifier.toString(f.getModifiers()); if (modifier.startsWith("public")) { set.add(f.getName()); } } } return set.toArray(new String[set.size()]); } /** * 获取对象的全部protected类型方法 * * @param className 需要获取的类名 * @param extendsMethod 是否获取继承来的方法 * @return 方法名数组 */ public final static String[] getProtectedMethod(String className, boolean extendsMethod) { Class classz = loadClass(className); Method[] methods; if (extendsMethod) { methods = classz.getMethods(); } else { methods = classz.getDeclaredMethods(); } Set<String> set = new HashSet<>(); if (methods != null) { for (Method f : methods) { String modifier = Modifier.toString(f.getModifiers()); if (modifier.startsWith("protected")) { set.add(f.getName()); } } } return set.toArray(new String[set.size()]); } /** * 获取对象的全部private类型方法 * * @param className 需要获取的类名 * @return 方法名数组 */ public final static String[] getPrivateMethod(String className) { Class classz = loadClass(className); Method[] methods = classz.getDeclaredMethods(); Set<String> set = new HashSet<>(); if (methods != null) { for (Method f : methods) { String modifier = Modifier.toString(f.getModifiers()); if (modifier.startsWith("private")) { set.add(f.getName()); } } } return set.toArray(new String[set.size()]); } /** * 获取对象的全部方法 * * @param className 需要获取的类名 * @param extendsMethod 是否获取继承来的方法 * @return 方法名数组 */ public final static String[] getMethod(String className, boolean extendsMethod) { Class classz = loadClass(className); Method[] methods; if (extendsMethod) { methods = classz.getMethods(); } else { methods = classz.getDeclaredMethods(); } Set<String> set = new HashSet<>(); if (methods != null) { for (Method f : methods) { set.add(f.getName()); } } return set.toArray(new String[set.size()]); } /** * 调用对象的setter方法 * * @param obj 对象 * @param att 属性名 * @param value 属性值 * @param type 属性类型 */ public final static void setter(Object obj, String att, Object value, Class<?> type) throws InvocationTargetException, IllegalAccessException { try { String name = att.substring(0, 1).toUpperCase() + att.substring(1); Method met = obj.getClass().getMethod("set" + name, type); met.invoke(obj, value); } catch (NoSuchMethodException e) { e.printStackTrace(); } } /** * 获取指定目录下所有的类名 * * @param path 包名 * @param childPackage 是否获取子包 */ public final static List<String> getClassName(String path, boolean childPackage) { List<String> fileNames = new ArrayList<>(); if (path.endsWith(".jar")) { fileNames.addAll(getClassNameByJar(path)); } else { fileNames = getClassNameByFile(path, childPackage); } return fileNames; } /** * 从项目文件获取某包下所有类 * * @param filePath 文件路径 * @param childPackage 是否遍历子包 * @return 类的完整名称 */ public final static List<String> getClassNameByFile(String filePath, boolean childPackage) { List<String> myClassName = new ArrayList<>(); List<File> files = FileUtil.listFile(filePath, childPackage); for (File file : files) { if (file.getName().endsWith(".class")) { String childFilePath = file.getPath(); int index = filePath.replaceAll("\\\\", ".").length(); childFilePath = childFilePath.replaceAll("\\\\", ".").substring(index, childFilePath.length()); myClassName.add(childFilePath); } } return myClassName; } /** * 从jar获取某包下所有类 * * @param jarPath jar文件路径 * @return 类的完整名称 */ public final static List<String> getClassNameByJar(String jarPath) { List<String> myClassName = new ArrayList<>(); try (JarFile jarFile = new JarFile(jarPath)) { Enumeration<JarEntry> entrys = jarFile.entries(); while (entrys.hasMoreElements()) { JarEntry jarEntry = entrys.nextElement(); String entryName = jarEntry.getName(); if (entryName.endsWith(".class")) { entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf(".")); myClassName.add(entryName); } } } catch (IOException e) { e.printStackTrace(); } return myClassName; } /** * 加载指定的类 * * @param className 需要加载的类 * @return 加载后的类 */ public final static Class loadClass(String className) { Class theClass = null; try { theClass = Class.forName(className); } catch (ClassNotFoundException e1) { logger.error("load class error:" + e1.getMessage()); e1.printStackTrace(); } return theClass; } /** * 获取jar包中的非*.class外的全部资源文件名字 * * @param jarPath jar文件路径 * @return 返回资源名称数组 */ public final static List<String> getResourceNameByJar(String jarPath) { List<String> resource = new ArrayList<>(); try (JarFile jarFile = new JarFile(jarPath)) { Enumeration<JarEntry> entrys = jarFile.entries(); while (entrys.hasMoreElements()) { JarEntry jarEntry = entrys.nextElement(); String entryName = jarEntry.getName(); if (!entryName.endsWith(".class") && !entryName.endsWith("/")) { resource.add(FilePathUtil.commandPath(jarPath) + "!" + entryName); } } } catch (IOException e) { e.printStackTrace(); } return resource; } /** * 获取jar包中的非*.class外的全部的以suffix结尾的资源文件 * * @param jarPath jar包的路径 * @param suffix 后缀名称 * @return 返回资源名称数组 */ public final static List<String> getResourceNameByJar(String jarPath, String suffix) { List<String> resource = new ArrayList<>(); try (JarFile jarFile = new JarFile(jarPath)) { Enumeration<JarEntry> entrys = jarFile.entries(); while (entrys.hasMoreElements()) { JarEntry jarEntry = entrys.nextElement(); String entryName = jarEntry.getName(); if (entryName.endsWith(suffix)) { resource.add(FilePathUtil.commandPath(jarPath) + "!" + entryName); } } } catch (IOException e) { logger.error(ExceptionUtil.stackTraceToString(e, UtilConstant.APP_PACKAGE)); } return resource; } /** * 获取一个类的父类 * * @param className 需要获取的类 * @return 父类的名称 */ public final static String getSuperClass(String className) { Class classz = loadClass(className); Class superclass = classz.getSuperclass(); return superclass.getName(); } /** * 获取一个雷的继承链 * * @param className 需要获取的类 * @return 继承类名的数组 */ public final static String[] getSuperClassChian(String className) { Class classz = loadClass(className); List<String> list = new ArrayList<>(); Class superclass = classz.getSuperclass(); String superName = superclass.getName(); if (!"java.lang.Object".equals(superName)) { list.add(superName); list.addAll(Arrays.asList(getSuperClassChian(superName))); } else { list.add(superName); } return list.toArray(new String[list.size()]); } /** * 获取一类实现的全部接口 * * @param className 需要获取的类 * @param extendsInterfaces 话说getInterfaces能全部获取到才对,然而测试的时候父类的接口并没有 * 因此就多除了这参数 * @return 实现接口名称的数组 */ public final static String[] getInterfaces(String className, boolean extendsInterfaces) { Class classz = loadClass(className); List<String> list = new ArrayList<>(); Class[] interfaces = classz.getInterfaces(); if (interfaces != null) { for (Class inter : interfaces) { list.add(inter.getName()); } } if (extendsInterfaces) { String[] superClass = getSuperClassChian(className); for (String c : superClass) { list.addAll(Arrays.asList(getInterfaces(c, false))); } } return list.toArray(new String[list.size()]); } }