Java遍历类路径所有类

简介: WalkClasspathAllClasses

首发于Enaium的个人博客


public class WalkClasspathAllClasses {
   
    public static void main(String[] args) throws URISyntaxException, IOException {
   
        List<URL> urls = new ArrayList<>();
        //获取Classpath
        if (WalkClasspathAllClasses.class.getClassLoader() instanceof URLClassLoader) {
   
            Collections.addAll(urls, ((URLClassLoader) WalkClasspathAllClasses.class.getClassLoader()).getURLs());
        } else {
   
            for (String s : System.getProperty("java.class.path").split(";")) {
   
                urls.add(new File(s).toURI().toURL());
            }
        }
        //遍历所有类
        walkAllClasses(urls).forEach(System.out::println);
    }

    private static Set<String> walkAllClasses(List<URL> urls) throws URISyntaxException, IOException {
   
        Set<String> classes = new HashSet<>();
        for (URL url : urls) {
   
            if (url.toURI().getScheme().equals("file")) {
   //判断Scheme是不是file
                File file = new File(url.toURI());
                if (!file.exists()) continue;//是存在
                if (file.isDirectory()) {
   //如果是目录
                    Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {
   //遍历所有文件
                        @Override
                        public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
   
                            if (path.toFile().getName().endsWith(".class")) {
   //判断是否为class后缀
                                //去除路径截取包名
                                String substring = path.toFile().getAbsolutePath().substring(file.getAbsolutePath().length());
                                if (substring.startsWith(File.separator)) {
   
                                    substring = substring.substring(1);
                                }
                                substring = substring.substring(0, substring.length() - 6);//去掉后缀
                                classes.add(substring.replace(File.separator, "."));//把路径替换为.
                            }
                            return super.visitFile(path, attrs);
                        }
                    });
                } else if (file.getName().endsWith(".jar")) {
   //如果是jar包
                    JarFile jarFile = new JarFile(file);
                    Enumeration<JarEntry> entries = jarFile.entries();
                    while (entries.hasMoreElements()) {
   //遍历所有文件
                        JarEntry jarEntry = entries.nextElement();
                        if (!jarEntry.getName().endsWith(".class")) continue;//判断后缀是否为class
                        String replace = jarEntry.getName().replace("/", ".");//把路径替换为.
                        classes.add(replace.substring(0, replace.length() - 6));//去掉后缀
                    }
                }
            }
        }
        return classes;
    }
}
目录
相关文章
|
3月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
112 9
|
6天前
|
安全 Java 编译器
JAVA泛型类的使用(二)
接上一篇继续介绍Java泛型的高级特性。3. **编译时类型检查**:尽管运行时发生类型擦除,编译器会在编译阶段进行严格类型检查,并允许通过`extends`关键字对类型参数进行约束,确保类型安全。4. **桥方法**:为保证多态性,编译器会生成桥方法以处理类型擦除带来的问题。5. **运行时获取泛型信息**:虽然泛型信息在运行时被擦除,但可通过反射机制部分恢复这些信息,例如使用`ParameterizedType`来获取泛型参数的实际类型。
|
6天前
|
安全 Java 编译器
JAVA泛型类的使用(一)
Java 泛型类是 JDK 5.0 引入的重要特性,提供编译时类型安全检测,增强代码可读性和可维护性。通过定义泛型类如 `Box&lt;T&gt;`,允许使用类型参数。其核心原理是类型擦除,即编译时将泛型类型替换为边界类型(通常是 Object),确保与旧版本兼容并优化性能。例如,`Box&lt;T&gt;` 编译后变为 `Box&lt;Object&gt;`,从而实现无缝交互和减少内存开销。
|
3月前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
200 58
|
2月前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
117 34
|
2月前
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
|
3月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
104 8
|
3月前
|
Java Android开发
Eclipse Java 构建路径
Eclipse Java 构建路径
56 3
|
3月前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
3月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。

热门文章

最新文章