ClassLoader和Class.forName()

时间:2013-02-15 09:57:02

标签: java classloader

我已经制作了一个自定义类加载器,我不知道如何“注册”它。

public static void main( String[] args ) throws Exception {
   File            jar   = new File( "Simple.jar" );
   FileInputStream fis   = new FileInputStream( jar );
   byte[]          bytes = new byte[(int)jar.length()];
   fis.read( bytes );
   fis.close();
   MemoryClassLoader cl = new MemoryClassLoader();
   cl.defineClasses( bytes );

   // 1: Following lines works well
   cl.findClass ( "help.Simple" )
      .getMethod( "main", new Class[]{ String[].class })
         .invoke( null, (Object)args );

   // 1: it works well
   cl.findClass ( "help.Simple" )
      .getMethod( "main", new Class[]{ String[].class })
         .invoke( null, (Object)args );

   // 2: it works well too
   Class.forName( "help.Simple", true, cl )
      .getMethod( "main", new Class[]{ String[].class })
         .invoke( null, (Object)args );

   // 3: it doesn't work
   Class.forName( "help.Simple" )
      .getMethod( "main", new Class[]{ String[].class })
         .invoke( null, (Object)args );
}

实际的MemoryClassloader更复杂,此处不详述。

该程序输出:

Hello, world!
Hello, world!
Exception in thread "main" java.lang.ClassNotFoundException: help.Simple
   at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
   at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
   at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
   at java.lang.Class.forName0(Native Method)
   at java.lang.Class.forName(Class.java:186)
   at loader.MemoryClassLoader.main(MemoryClassLoader.java:76)

线条“Hello,world!”由help.Simple.main( String[] args )打印。 我的类加载器正确加载了类help.Simple。 但调用它的第三种方式Class.forName()不起作用。 为什么以及如何将我使用自定义类加载器加载的类添加到默认系统类加载器加载的“标准”类列表中?

1 个答案:

答案 0 :(得分:3)

Class.forName默认使用已加载当前类(包含main方法的类)的类加载器。我认为在这种情况下让它工作的唯一方法是使用重载方法接受另一个类加载器。

当在类加载器本身加载的其他类中使用时,它应该可以正常工作。

Class.forName( "help.Simple", true, cl )