读取Class文件

对于已经出现在类路径上的类,如果如需要动态装载,可以使用classloader#loadClass或者Class#forname来实现。
那么对于不在类路径的.class文件,需要装载的时候就要用到URLClassLoader了。
I believe it's a ClassLoader you're after.

I suggest you start by looking at the example below which loads class files that are not on the class path.

// Create a File object on the root of the directory containing the class file
File file = new File("c:\\myclasses\\");

try {
    // Convert File to a URL
    URL url = file.toURL();          // file:/c:/myclasses/
    URL[] urls = new URL[]{url};

    // Create a new class loader with the directory
    ClassLoader cl = new URLClassLoader(urls);

    // Load in the class; MyClass.class should be located in
    // the directory file:/c:/myclasses/com/mycompany
    Class cls = cl.loadClass("com.mycompany.MyClass");
} catch (MalformedURLException e) {
} catch (ClassNotFoundException e) {
}

这里有两个点需要注意

Package name is a part of full class name, not classpath item, so you need the following:

URL[] urls = {new URL("file:/F:/badge-dao/bin")}; 
...
selectedClass = classLoader.loadClass("com.badge.dao.impl.BadgeDaoImpl"); 
In your original code classloader can find a file named BadgeDaoImpl.class in file:/F:/badge-dao/bin/com/badge/dao/impl/, but its full class name (com.badge.dao.impl.BadgeDaoImpl) doesn't match the requested one (BadgeDaoImpl), therefore classloader throws a NoClassDefFoundError. Since you are catching only ClassNotFoundException, it looks like control silently passes to the finally block. When you change folder or class names so that .class file can't be found, ClassNotFoundException is thrown as expected.
  • URL:只能包含类路径,不能包括包名,虽然包名也是以文件夹的形式呈现,但包名是类名的一部分,所以类路径与包名中的文件夹名要严格区分,类路径就是类的根目录,也就是包名的第一个部分所在的目录
  • URL与jar : URL如果以'/'(windows'')结尾,那么这个URL代表了搜索类的目录,反之代表了jar文件
From just glancing at the javadocs of [URLClassLoader](http://docs.oracle.com/javase/7/docs/api/java/net/URLClassLoader.html#URLClassLoader%28java.net.URL%5b%5d%29):
Any URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL is assumed to refer to a JAR file which will be downloaded and opened as needed.

The URL you're specifying ends with a slash, so the class loader expects to see .class
 files in that directory. Try specifying the full path to the JAR in the URL

装载了类文件之后,这里有个坑。。

类中的各个字段

 // Caches for certain reflective results
    private static boolean useCaches = true;
    private volatile transient SoftReference<Field[]> declaredFields;
    private volatile transient SoftReference<Field[]> publicFields;
    private volatile transient SoftReference<Method[]> declaredMethods;
    private volatile transient SoftReference<Method[]> publicMethods;
    private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
    private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
    // Intermediate results for getFields and getMethods
    private volatile transient SoftReference<Field[]> declaredPublicFields;
    private volatile transient SoftReference<Method[]> declaredPublicMethods;

可以看到都是软引用,目的应该是缓存
而在debug的时候,装载了类文件,在没有调用相关函数的时候,这些字段都显示为null,调用了之后才会有对象,并不是读到了空的类,这么设计的目的可能是为了方便JVM回收吧,以后再详细看看。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,084评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 33,176评论 18 399
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,148评论 6 342
  • ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于某些框架开发者来说却非常常见...
    时待吾阅读 4,761评论 0 1
  • 很多时候,不想走了,因为累了; 很多时候,不想停留,因为想一直走; 很多时候,不想安于现状,因为要改变; 很多时候...
    dreamer翟翟阅读 2,682评论 0 2

友情链接更多精彩内容