Class.forName详解
(2011-02-11 07:45:39)
Class.forName(xxx.xx.xx) 返回一个类
首先你要明白在java里面任何class都要装载在虚拟机上才能运行。这句话就是装载类用的(和new 不一样,要分清楚)。
至于什么时候用,可以考虑一下这个问题,给出一个字符串变量,它代表一个类的包名和类名,怎么实例化它?只有提到的这个方法了,不过要再加一点。
A a = (A)Class.forName("pacage.A").newInstance();
这和
A a = new A();
是一样的效果。
A a = (A)Class.forName("pacage.A").newInstance();
这和
A a = new A();
是一样的效果。
相关的补充问题
JVM会执行静态代码段,要记住一个概念,静态代码是和class绑定的,class装载成功就表示执行了静态代码了,以后也就不会再走这段静态代码了。
String str = 用户输入的字符串
Class t = Class.forName(str);
t.newInstance();
Class t = Class.forName(str);
t.newInstance();
class c = Class.forName(“Example”);
factory = (ExampleInterface)c.newInstance();
String className = "Example";
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();
String className = readfromXMlConfig;//从xml 配置文件中获得字符串
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();
只要它们继承ExampleInterface也就是factory就可以。
而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器。
forName() 和 ClassLoader 的 loadClass 方法。
1、forName(String className)单参数时, initialize=true
2、forName(String className, boolean initialize, ClassLoader loader)
1、loadClass(String name)单参数时, resolve=false
2、loadClass(String name, boolean resolve)
velocity中Class.forName("") 报ClassNotFoundException的问题
lvjun106 2012-04-25
近日在做velocity自定义指令时,经常碰到ClassNotFoundException.
查看源代码,
原来VELOCITY在加载自定义指令时用的是Class.forName,生成新对象,
杯具的是我自定义的class是与velocity.jar不在同一个项目中,更不在同一级目录中,而Class.forName,如果这么写的话,是默认用dependClass的类加载器,即本身类加载器,所以才会报出ClassNotFoundException.
解决方案其实只要把类加载器换成当前线程的即可。
Thread.currentThread().getContextClassLoader()
在此想问问各位大神,JVM在调用一个JAR时是怎样生成一个classLoader的?
查看源代码,
- private void loadDirective(String directiveClass, String caption)
- {
- try
- {
- Object o = Class.forName(directiveClass).newInstance();
- if(o instanceof Directive)
- {
- Directive directive = (Directive)o;
- runtimeDirectives.put(directive.getName(), directive);
- info((new StringBuilder("Loaded ")).append(caption).append(" Directive: ").append(directiveClass).toString());
- } else
- {
- error((new StringBuilder(String.valueOf(caption))).append(" Directive ").append(directiveClass).append(" is not org.apache.velocity.runtime.directive.Directive.").append(" Ignoring. ").toString());
- }
- }
- catch(Exception e)
- {
- error((new StringBuilder("Exception Loading ")).append(caption).append(" Directive: ").append(directiveClass).append(" : ").append(e).toString());
- }
- }
原来VELOCITY在加载自定义指令时用的是Class.forName,生成新对象,
杯具的是我自定义的class是与velocity.jar不在同一个项目中,更不在同一级目录中,而Class.forName,如果这么写的话,是默认用dependClass的类加载器,即本身类加载器,所以才会报出ClassNotFoundException.
解决方案其实只要把类加载器换成当前线程的即可。
Thread.currentThread().getContextClassLoader()
在此想问问各位大神,JVM在调用一个JAR时是怎样生成一个classLoader的?