Can you find all classes in a package using reflection?

前端 未结 27 3035
不知归路
不知归路 2020-11-21 05:24

Is it possible to find all classes or interfaces in a given package? (Quickly looking at e.g. Package, it would seem like no.)

27条回答
  •  清歌不尽
    2020-11-21 05:43

    You need to look up every class loader entry in the class path:

        String pkg = "org/apache/commons/lang";
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        URL[] urls = ((URLClassLoader) cl).getURLs();
        for (URL url : urls) {
            System.out.println(url.getFile());
            File jar = new File(url.getFile());
            // ....
        }   
    

    If entry is directory, just look up in the right subdirectory:

    if (jar.isDirectory()) {
        File subdir = new File(jar, pkg);
        if (!subdir.exists())
            continue;
        File[] files = subdir.listFiles();
        for (File file : files) {
            if (!file.isFile())
                continue;
            if (file.getName().endsWith(".class"))
                System.out.println("Found class: "
                        + file.getName().substring(0,
                                file.getName().length() - 6));
        }
    }   
    

    If the entry is the file, and it's jar, inspect the ZIP entries of it:

    else {
        // try to open as ZIP
        try {
            ZipFile zip = new ZipFile(jar);
            for (Enumeration entries = zip
                    .entries(); entries.hasMoreElements();) {
                ZipEntry entry = entries.nextElement();
                String name = entry.getName();
                if (!name.startsWith(pkg))
                    continue;
                name = name.substring(pkg.length() + 1);
                if (name.indexOf('/') < 0 && name.endsWith(".class"))
                    System.out.println("Found class: "
                            + name.substring(0, name.length() - 6));
            }
        } catch (ZipException e) {
            System.out.println("Not a ZIP: " + e.getMessage());
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
    }
    

    Now once you have all class names withing package, you can try loading them with reflection and analyze if they are classes or interfaces, etc.

提交回复
热议问题