千家信息网

如何用Java反射获取包下所有类

发表于:2024-09-26 作者:千家信息网编辑
千家信息网最后更新 2024年09月26日,本篇内容主要讲解"如何用Java反射获取包下所有类",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何用Java反射获取包下所有类"吧!我就废话不多说了,大
千家信息网最后更新 2024年09月26日如何用Java反射获取包下所有类

本篇内容主要讲解"如何用Java反射获取包下所有类",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何用Java反射获取包下所有类"吧!

我就废话不多说了,大家还是直接看代码吧~

/**     * 根据包名获取包下面所有的类名     *     * @param pack     * @return     * @throws Exception     */    public static Set> getClasses(String pack) throws Exception {        // 第一个class类的集合        Set> classes = new LinkedHashSet>();        // 是否循环迭代        boolean recursive = true;        // 获取包的名字 并进行替换        String packageName = pack;        String packageDirName = packageName.replace('.', '/');        // 定义一个枚举的集合 并进行循环来处理这个目录下的things        Enumeration dirs;        try {            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);            // 循环迭代下去            while (dirs.hasMoreElements()) {                // 获取下一个元素                URL url = dirs.nextElement();                // 得到协议的名称                String protocol = url.getProtocol();                // 如果是以文件的形式保存在服务器上                if ("file".equals(protocol)) {                    // 获取包的物理路径                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");                    // 以文件的方式扫描整个包下的文件 并添加到集合中                    findClassesInPackageByFile(packageName, filePath, recursive, classes);                } else if ("jar".equals(protocol)) {                    // 如果是jar包文件                    // 定义一个JarFile                    System.out.println("jar类型的扫描");                    JarFile jar;                    try {                        // 获取jar                        jar = ((JarURLConnection) url.openConnection()).getJarFile();                        // 从此jar包 得到一个枚举类                        Enumeration entries = jar.entries();                        findClassesInPackageByJar(packageName, entries, packageDirName, recursive, classes);                    } catch (IOException e) {                        // log.error("在扫描用户定义视图时从jar包获取文件出错");                        e.printStackTrace();                    }                }            }        } catch (IOException e) {            e.printStackTrace();        }        return classes;    }
/**     * 以文件的形式来获取包下的所有Class     *     * @param packageName     * @param packagePath     * @param recursive     * @param classes     */    private static void findClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, Set> classes) {        // 获取此包的目录 建立一个File        File dir = new File(packagePath);        // 如果不存在或者 也不是目录就直接返回        if (!dir.exists() || !dir.isDirectory()) {            // log.warn("用户定义包名 " + packageName + " 下没有任何文件");            return;        }        // 如果存在 就获取包下的所有文件 包括目录        File[] dirfiles = dir.listFiles(new FileFilter() {            // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)            @Override            public boolean accept(File file) {                return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));            }        });        // 循环所有文件        for (File file : dirfiles) {            // 如果是目录 则继续扫描            if (file.isDirectory()) {                findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);            } else {                // 如果是java类文件 去掉后面的.class 只留下类名                String className = file.getName().substring(0, file.getName().length() - 6);                try {                    // 添加到集合中去                    // classes.add(Class.forName(packageName + '.' +                    // className));                    // 经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净                    classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));                } catch (ClassNotFoundException e) {                    // log.error("添加用户自定义视图类错误 找不到此类的.class文件");                    e.printStackTrace();                }            }        }    }
 /**     * 以jar的形式来获取包下的所有Class     *     * @param packageName     * @param entries     * @param packageDirName     * @param recursive     * @param classes     */    private static void findClassesInPackageByJar(String packageName, Enumeration entries, String packageDirName, final boolean recursive, Set> classes) {        // 同样的进行循环迭代        while (entries.hasMoreElements()) {            // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件            JarEntry entry = entries.nextElement();            String name = entry.getName();            // 如果是以/开头的            if (name.charAt(0) == '/') {                // 获取后面的字符串                name = name.substring(1);            }            // 如果前半部分和定义的包名相同            if (name.startsWith(packageDirName)) {                int idx = name.lastIndexOf('/');                // 如果以"/"结尾 是一个包                if (idx != -1) {                    // 获取包名 把"/"替换成"."                    packageName = name.substring(0, idx).replace('/', '.');                }                // 如果可以迭代下去 并且是一个包                if ((idx != -1) || recursive) {                    // 如果是一个.class文件 而且不是目录                    if (name.endsWith(".class") && !entry.isDirectory()) {                        // 去掉后面的".class" 获取真正的类名                        String className = name.substring(packageName.length() + 1, name.length() - 6);                        try {                            // 添加到classes                            classes.add(Class.forName(packageName + '.' + className));                        } catch (ClassNotFoundException e) {                            // .error("添加用户自定义视图类错误 找不到此类的.class文件");                            e.printStackTrace();                        }                    }                }            }        }    }

补充:通过java反射机制获取该类的所有属性类型、值、

方法使用了这俩个包下的 field 和method

import java.lang.reflect.Field;import java.lang.reflect.Method;
public static void getObjectValue(Object object) throws Exception {                //我们项目的所有实体类都继承BaseDomain (所有实体基类:该类只是串行化一下)                //不需要的自己去掉即可                if (object != null && object instanceof BaseDomain) {//if (object!=null )  ----begin                        // 拿到该类                        Class clz = object.getClass();                        // 获取实体类的所有属性,返回Field数组                        Field[] fields = clz.getDeclaredFields();                         for (Field field : fields) {// --for() begin                                System.out.println(field.getGenericType());//打印该类的所有属性类型                                 // 如果类型是String                                if (field.getGenericType().toString().equals(                                                "class java.lang.String")) { // 如果type是类类型,则前面包含"class ",后面跟类名                                        // 拿到该属性的gettet方法                                        /**                                         * 这里需要说明一下:他是根据拼凑的字符来找你写的getter方法的                                         * 在Boolean值的时候是isXXX(默认使用ide生成getter的都是isXXX)                                         * 如果出现NoSuchMethod异常 就说明它找不到那个gettet方法 需要做个规范                                         */                                        Method m = (Method) object.getClass().getMethod(                                                        "get" + getMethodName(field.getName()));                                         String val = (String) m.invoke(object);// 调用getter方法获取属性值                                        if (val != null) {                                                System.out.println("String type:" + val);                                        }                                 }                                 // 如果类型是Integer                                if (field.getGenericType().toString().equals(                                                "class java.lang.Integer")) {                                        Method m = (Method) object.getClass().getMethod(                                                        "get" + getMethodName(field.getName()));                                        Integer val = (Integer) m.invoke(object);                                        if (val != null) {                                                System.out.println("Integer type:" + val);                                        }                                 }                                 // 如果类型是Double                                if (field.getGenericType().toString().equals(                                                "class java.lang.Double")) {                                        Method m = (Method) object.getClass().getMethod(                                                        "get" + getMethodName(field.getName()));                                        Doubleval = (Double) m.invoke(object);                                        if (val != null) {                                                System.out.println("Double type:" + val);                                        }                                 }                                 // 如果类型是Boolean 是封装类                                if (field.getGenericType().toString().equals(                                                "class java.lang.Boolean")) {                                        Method m = (Method) object.getClass().getMethod(                                                        field.getName());                                        Boolean val = (Boolean) m.invoke(object);                                        if (val != null) {                                                System.out.println("Boolean type:" + val);                                        }                                 }                                 // 如果类型是boolean 基本数据类型不一样 这里有点说名如果定义名是 isXXX的 那就全都是isXXX的                                // 反射找不到getter的具体名                                if (field.getGenericType().toString().equals("boolean")) {                                        Method m = (Method) object.getClass().getMethod(                                                        field.getName());                                        Boolean val = (Boolean) m.invoke(object);                                        if (val != null) {                                                System.out.println("boolean type:" + val);                                        }                                 }                                // 如果类型是Date                                if (field.getGenericType().toString().equals(                                                "class java.util.Date")) {                                        Method m = (Method) object.getClass().getMethod(                                                        "get" + getMethodName(field.getName()));                                        Dateval = (Date) m.invoke(object);                                        if (val != null) {                                                System.out.println("Date type:" + val);                                        }                                 }                                // 如果类型是Short                                if (field.getGenericType().toString().equals(                                                "class java.lang.Short")) {                                        Method m = (Method) object.getClass().getMethod(                                                        "get" + getMethodName(field.getName()));                                        Short val = (Short) m.invoke(object);                                        if (val != null) {                                                System.out.println("Short type:" + val);                                        }                                 }                                // 如果还需要其他的类型请自己做扩展                         }//for() --end                                        }//if (object!=null )  ----end        }         // 把一个字符串的第一个字母大写、效率是最高的、        private static String getMethodName(String fildeName) throws Exception{                byte[] items = fildeName.getBytes();                items[0] = (byte) ((char) items[0] - 'a' + 'A');                return new String(items);        }

到此,相信大家对"如何用Java反射获取包下所有类"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0