读取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 declaredFields;
    private volatile transient SoftReference publicFields;
    private volatile transient SoftReference declaredMethods;
    private volatile transient SoftReference publicMethods;
    private volatile transient SoftReference[]> declaredConstructors;
    private volatile transient SoftReference[]> publicConstructors;
    // Intermediate results for getFields and getMethods
    private volatile transient SoftReference declaredPublicFields;
    private volatile transient SoftReference declaredPublicMethods;

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

你可能感兴趣的:(读取Class文件)