【Java】ClassLoarder 加载 jar 包里面的 class

本文介绍了如何使用Java的ClassLoader加载jar包内部的class文件,包括不同启动方式下的测试代码,如IDEA本地启动和命令行使用java -cp的方式。其次,详细解析了JarURL,查看jar文件内的所有jarEntry,并探讨了实例化jar中Class文件的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java ClassLoarder 加载 jar 包里面的 class

一、不同启动方式的测试代码

ClassLoader cl = JarClApp.class.getClassLoader();
String pkg = JarClApp.class.getPackage().getName();
System.out.printf("Find pkg: %s, cl: %s %n", pkg, cl);
String path = pkg.replaceAll("\\.", "/");
URL resource = cl.getResource(path);
assert resource != null;
System.out.printf("Find resource %s, protocol: %s %n", resource, resource.getProtocol());
  • idea 本地启动结果
Find pkg: com.bheternal.jhome.lang.cl, cl: sun.misc.Launcher$AppClassLoader@18b4aac2 
Find resource file:/Users/zain/code/1.my-code/JHome/lang/java-classloader/target/classes/com/bheternal/jhome/lang/cl, protocol: file 
  • 命令 java -cp 启动结果
Find pkg: com.bheternal.jhome.lang.cl, cl: sun.misc.Launcher$AppClassLoader@5c647e05 
Find resource jar:file:/Users/zain/code/1.my-code/JHome/lang/java-classloader/target/java-classloader-1.0-SNAPSHOT.jar!/com/bheternal/jhome/lang/cl, protocol: jar

二、JarURL 解析

  • 属性
private static void handlerJar(URL resource) throws IOException {
  JarURLConnection jarUrl = (JarURLConnection) resource.openConnection();

  URL jarFileUrl = jarUrl.getJarFileURL();
  Attributes attributes = jarUrl.getAttributes();
  String entryName = jarUrl.getEntryName();
  JarEntry jarEntry = jarUrl.getJarEntry();
  JarFile jarFile = jarUrl.getJarFile();


  System.out.printf("jarFileUrl: %s %n", jarFileUrl);
  System.out.printf("attributes: %s %n", attributes);
  System.out.printf("entryName: %s %n", entryName);
  System.out.printf("jarEntry: %s %n", jarEntry);
  System.out.printf("jarFile: %s %n", jarFile);

}
jarFileUrl: file:/Users/zain/code/1.my-code/JHome/lang/java-classloader/target/java-classloader-1.0-SNAPSHOT.jar 
attributes: null 
entryName: com/bheternal/jhome/lang/cl 
jarEntry: com/bheternal/jhome/lang/cl/ 
jarFile: sun.net.www.protocol.jar.URLJarFile@135fbaa4 
  • jarFile 下所有 jarEntry 查看
private static void handlerJarFile(JarFile jarFile) {

  jarFile.stream().forEach(jarEntry -> {

    System.out.printf("jarEntry: %s %n", jarEntry);

  });

}
jarEntry: META-INF/ 
jarEntry: META-INF/MANIFEST.MF 
jarEntry: com/ 
jarEntry: com/bheternal/ 
jarEntry: com/bheternal/jhome/ 
jarEntry: com/bheternal/jhome/lang/ 
jarEntry: com/bheternal/jhome/lang/cl/ 
jarEntry: com/bheternal/jhome/lang/cl/ClCategoryApp.class 
jarEntry: com/bheternal/jhome/lang/cl/candidate/ 
jarEntry: com/bheternal/jhome/lang/cl/candidate/DemoB.class 
jarEntry: com/bheternal/jhome/lang/cl/candidate/DemoC.class 
jarEntry: com/bheternal/jhome/lang/cl/candidate/DemoA.class 
jarEntry: com/bheternal/jhome/lang/cl/JarClApp.class 
jarEntry: META-INF/maven/ 
jarEntry: META-INF/maven/com.bheternal.jhome/ 
jarEntry: META-INF/maven/com.bheternal.jhome/java-classloader/ 
jarEntry: META-INF/maven/com.bheternal.jhome/java-classloader/pom.xml 
jarEntry: META-INF/maven/com.bheternal.jhome/java-classloader/pom.properties 

三、实例化 Jar 的 Class 文件

private static void handlerJarFile(JarFile jarFile) throws Exception {

  // jarFile.stream().forEach(jarEntry -> {
  //     System.out.printf("jarEntry: %s %n", jarEntry);
  // });

  List<JarEntry> jarEntries = new LinkedList<>();
  jarFile.stream()
    .filter(jarEntry -> jarEntry.getName().startsWith(path + File.separator + "candidate"))
    .filter(jarEntry -> jarEntry.getName().endsWith(".class"))
    .forEach(jarEntry -> {
      System.out.printf("jarEntry: %s %n", jarEntry);
      jarEntries.add(jarEntry);
    });

  for (JarEntry jarEntry : jarEntries) {
    String classPath = jarEntry.getName();
    String classPkg = classPath
      .replaceAll(File.separator, "\\.")
      .replaceAll("\\.class", "");

    Class<?> tClass = Class.forName(classPkg);
    System.out.printf("tClass: %s %n", tClass);
  }

}
tClass: class com.bheternal.jhome.lang.cl.candidate.DemoB
tClass: class com.bheternal.jhome.lang.cl.candidate.DemoC
tClass: class com.bheternal.jhome.lang.cl.candidate.DemoA
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值