反射通过接口反射出所有子类

注意此处,如果要通过接口反射字类的话,一定会去获取某个文件夹中的类来获取。

此时要注意了,如果在没有打包之前是可以获取到的,但是如果日后,要查询的文件夹是在jar包中则就获取不到了。因此此处代码就是我写的即可以获取本地,也可以获取jar中的文件夹。

ClassUtils类:

package cn.teddy.sp.common.utils;

 

import java.io.File;

import java.io.FileFilter;

import java.io.IOException;

import java.lang.annotation.Annotation;

import java.lang.reflect.Method;

import java.net.JarURLConnection;

import java.net.URL;

import java.net.URLClassLoader;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.List;

import java.util.Map;

import java.util.jar.JarEntry;

import java.util.jar.JarFile;

 

import org.apache.commons.lang.StringUtils;

import org.springframework.stereotype.Service;

 

import cn.teddy.sp.common.constant.partner.BaseConstantInterface;

/**

 * 反射获取类信息utils

 * @author xiaoyuhan

 *

 */

public class ClassUtils {

       /**

        *  测试获取本地或者jar中,给一个接口,返回这个接口的所有实现类(要求接口和实现类必须在一个包中)

        *

        * @param args

        */

       public static void main(String[] args) {

              List s = getAllImplClassesByInterface(BaseConstantInterface.class);

              for (String string : s) {

                     System.out.println(string);

              }

       }

 

       /**

        * 给一个接口,返回这个接口的所有实现类

        */

 

       public static List getAllImplClassesByInterface(Class c) {

              List returnClassList = new ArrayList();// 返回结果

              // 如果不是一个接口,则不做处理

              if (c.isInterface()) {

                     String packageName = c.getPackage().getName();// 获得当前包名

                     // System.out.println(packageName);

                     try {

                            List> allClass = getClassList(packageName, false, null);// 获得当前包下以及包下的所有类

                            for (int i = 0; i < allClass.size(); i++) {

                                   /**

                                    * 判定此 Class 对象所表示的类或接口与指定的 Class 参数cls所表示的类或接口是否相同, 或是否是其超类或(超)接口,如果是则返回

                                    * true,否则返回 false。

                                    */

                                   if (c.isAssignableFrom(allClass.get(i))) {

                                          if (!c.equals(allClass.get(i))) {// 本身加不进去

                                                 Class clazz = allClass.get(i);

                                                 // 如果类被@Deprecated修饰了,就不添加了

                                                 if (clazz.getAnnotation(Deprecated.class) != null) {

                                                        continue;

                                                 }

                                                 String cs = allClass.get(i).toString();

                                                 returnClassList.add(cs.substring(cs.indexOf("class ") + 6));

                                          }

                                   }

                            }

                     } catch (Exception e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                     }

              }

              return returnClassList;

       }

 

       /**

        * 获取本地包中或者jar包中的,某个包中的所有类名

        *

        * @param pkgName

        *            本地包中或者jar包中的包名称,注意是包名称

        * @param isRecursive

        *            ture 外加获取包中子包中的类 false 不获取包中子包的类

        * @param annotation

        *            类上边加的注解

        * @return

        */

       public static List> getClassList(String pkgName, boolean isRecursive,

                     Class annotation) {

              List> classList = new ArrayList>();

              ClassLoader loader = Thread.currentThread().getContextClassLoader();

              try {

                     // 按文件的形式去查找

                     String strFile = pkgName.replaceAll("\\.", "/");

                     Enumeration urls = loader.getResources(strFile);

                     while (urls.hasMoreElements()) {

                            URL url = urls.nextElement();

                            if (url != null) {

                                   String protocol = url.getProtocol();

                                   String pkgPath = url.getPath();

                                   // System.out.println("protocol:" + protocol +" path:" + pkgPath);

                                   if ("file".equals(protocol)) {

                                          // 本地自己可见的代码

                                          findClassName(classList, pkgName, pkgPath, isRecursive, annotation);

                                   } else if ("jar".equals(protocol)) {

                                          // 引用第三方jar的代码

                                          findClassName(classList, pkgName, url, isRecursive, annotation);

                                   }

                            }

                     }

              } catch (IOException e) {

                     e.printStackTrace();

              }

 

              return classList;

       }

 

       public static void findClassName(List> clazzList, String pkgName, String pkgPath, boolean isRecursive,

                     Class annotation) {

              if (clazzList == null) {

                     return;

              }

              File[] files = filterClassFiles(pkgPath);// 过滤出.class文件及文件夹

              // System.out.println("files:" +((files == null)?"null" : "length=" +

              // files.length));

              if (files != null) {

                     for (File f : files) {

                            String fileName = f.getName();

                            if (f.isFile()) {

                                   // .class 文件的情况

                                   String clazzName = getClassName(pkgName, fileName);

                                   addClassName(clazzList, clazzName, annotation);

                            } else {

                                   // 文件夹的情况

                                   if (isRecursive) {

                                          // 需要继续查找该文件夹/包名下的类

                                          String subPkgName = pkgName + "." + fileName;

                                          String subPkgPath = pkgPath + "/" + fileName;

                                          findClassName(clazzList, subPkgName, subPkgPath, true, annotation);

                                   }

                            }

                     }

              }

       }

 

       /**

        * 第三方Jar类库的引用。

        *

        * @throws IOException

        */

       public static void findClassName(List> clazzList, String pkgName, URL url, boolean isRecursive,

                     Class annotation) throws IOException {

              JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();

              JarFile jarFile = jarURLConnection.getJarFile();

              // System.out.println("jarFile:" + jarFile.getName());

              Enumeration jarEntries = jarFile.entries();

              while (jarEntries.hasMoreElements()) {

                     JarEntry jarEntry = jarEntries.nextElement();

                     String jarEntryName = jarEntry.getName(); // 类似:sun/security/internal/interfaces/TlsMasterSecret.class

                     String clazzName = jarEntryName.replace("/", ".");

                     int endIndex = clazzName.lastIndexOf(".");

                     String prefix = null;

                     if (endIndex > 0) {

                            String prefix_name = clazzName.substring(0, endIndex);

                            endIndex = prefix_name.lastIndexOf(".");

                            if (endIndex > 0) {

                                   prefix = prefix_name.substring(0, endIndex);

                            }

                     }

                     if (prefix != null && jarEntryName.endsWith(".class")) {

                            // System.out.println("prefix:" + prefix +" pkgName:" + pkgName);

                            if (prefix.equals(pkgName)) {

                                   // System.out.println("jar entryName:" + jarEntryName);

                                   addClassName(clazzList, clazzName, annotation);

                            } else if (isRecursive && prefix.startsWith(pkgName)) {

                                   // 遍历子包名:子类

                                   // System.out.println("jar entryName:" + jarEntryName +" isRecursive:" +

                                   // isRecursive);

                                   addClassName(clazzList, clazzName, annotation);

                            }

                     }

              }

       }

 

       private static File[] filterClassFiles(String pkgPath) {

              if (pkgPath == null) {

                     return null;

              }

              // 接收 .class 文件 或 类文件夹

              return new File(pkgPath).listFiles(new FileFilter() {

                     @Override

                     public boolean accept(File file) {

                            return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();

                     }

              });

       }

 

       private static String getClassName(String pkgName, String fileName) {

              int endIndex = fileName.lastIndexOf(".");

              String clazz = null;

              if (endIndex >= 0) {

                     clazz = fileName.substring(0, endIndex);

              }

              String clazzName = null;

              if (clazz != null) {

                     clazzName = pkgName + "." + clazz;

              }

              return clazzName;

       }

 

       private static void addClassName(List> clazzList, String clazzName,

                     Class annotation) {

              if (clazzList != null && clazzName != null) {

                     Class clazz = null;

                     try {

                            if (clazzName.endsWith(".class")) {

                                   clazzName = clazzName.substring(0, clazzName.indexOf(".class"));

                            }

                            clazz = Class.forName(clazzName);

                     } catch (ClassNotFoundException e) {

                            e.printStackTrace();

                     }

                     // System.out.println("isAnnotation=" + clazz.isAnnotation() +" author:" +

                     // clazz.isAnnotationPresent(author.class));

                     if (clazz != null) {

                            if (annotation == null) {

                                   clazzList.add(clazz);

                                   // System.out.println("add:" + clazz);

                            } else if (clazz.isAnnotationPresent(annotation)) {

                                   clazzList.add(clazz);

                                   // System.out.println("add annotation:" + clazz);

                            }

                     }

              }

       }

 

       /**

        * 通过类路径和方法名称,获取某个类的,无参方法返回值(String)

        *

        * @param methordName 方法名称

        * @param classPathName  类路径

        * @return

        */

       public static String getMethordResult(String classPathName, String methordName) {

              Class clazz = null;

              Object obj = null;

              Method m3;

              try {

                     clazz = Class.forName(classPathName);

                     obj = clazz.newInstance();

                     m3 = clazz.getMethod(methordName);

                     return (String) m3.invoke(obj);

              } catch (Exception e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

                     return null;

              }

       }

 

       /**

        * 通过类路径和方法名称和参数,获取某个类的,带参方法返回值(Object)

        *

        * @param methordName 方法名称

        * @param classPathName  类路径

        * @return

        */

       public static Object getMethordResult(String classPathName, String methordName, String... strings) {

              Class clazz = null;

              Object obj = null;

              Method m3;

              try {

                     clazz = Class.forName(classPathName);

                     obj = clazz.newInstance();

                     Class [] cs = new Class[strings.length];

                     for(int i =0;i

                            cs[i]=String.class;

                     }

                     m3 = clazz.getMethod(methordName, cs);

                     return m3.invoke(obj, strings);

              } catch (Exception e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

                     return null;

              }

       }

 

       /**

        * 获取指定jar中的所有类,所有方法,所有属性 测试

        * 使用getJarName("/Library/Java/JavaVirtualMachines/apache-tomcat-8.5.30/webapps/ROOT/WEB-INF/lib/sp-common-1.0-SNAPSHOT.jar");

        *

        * @param jarFile    jar包的路径

        * @throws Exception

        */

       public static void getJarName(String jarFile) throws Exception {

              try {

                     // 通过将给定路径名字符串转换为抽象路径名来创建一个新File实例

                     File f = new File(jarFile);

                     URL url1 = f.toURI().toURL();

                     URLClassLoader myClassLoader = new URLClassLoader(new URL[] { url1 },

                                   Thread.currentThread().getContextClassLoader());

 

                     // 通过jarFile和JarEntry得到所有的类

                     JarFile jar = new JarFile(jarFile);

                     // 返回zip文件条目的枚举

                     Enumeration enumFiles = jar.entries();

                     JarEntry entry;

 

                     // 测试此枚举是否包含更多的元素

                     while (enumFiles.hasMoreElements()) {

                            entry = (JarEntry) enumFiles.nextElement();

                            if (entry.getName().indexOf("META-INF") < 0) {

                                   String classFullName = entry.getName();

                                   if (!classFullName.endsWith(".class")) {

                                          classFullName = classFullName.substring(0, classFullName.length() - 1);

                                   } else {

                                          // 去掉后缀.class

                                          String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");

                                          Class myclass = myClassLoader.loadClass(className);

                                          // 打印类名

                                          // System.out.println("*****************************");

                                          System.out.println("全类名:" + className);

 

                                          // 得到类中包含的属性

                                          Method[] methods = myclass.getMethods();

                                          for (Method method : methods) {

                                                 String methodName = method.getName();

                                                 System.out.println("方法名称:" + methodName);

                                                 Class[] parameterTypes = method.getParameterTypes();

                                                 for (Class clas : parameterTypes) {

                                                        // String parameterName = clas.getName();

                                                        String parameterName = clas.getSimpleName();

                                                        System.out.println("参数类型:" + parameterName);

                                                 }

                                                 System.out.println("==========================");

                                          }

                                   }

                            }

                     }

              } catch (IOException e) {

                     e.printStackTrace();

              }

       }

}

 

 

你可能感兴趣的:(java)