关于Class.forName("...")与Class.forName("...").newInstance()区别

阅读更多
Demo   d   =   new   DerivedDromDemo();     //写代码编译时就确定了。

Demo   d   =   Class.forName( "DerivedFromDemoButWeCantKnowHisName ").newInstance();   //   运行时再来,这个类名字可以计算得出,比如读取配置文件,只要他能完成   Demo   d   =   (Demo)   instance;操作就行。


Java   中很多     Spi   工厂类都是这种方式工作,
public   abstract   class   Factory   {
      public   static   Factory   getInstance(String   name){
            //   读取配置文件,查找信息。
          InputStream   in   =   Thread.getContextClassLoader().getResourceAsStream( "/config.properties ");

          Properties   config   =   new   Properties();
            config.load(in);
     
          String   clazz   =   config.getProperty(name);

//读到了一个工厂类完成具体事情,   这个类应该实现了   抽象业务方法,比如下面的   createSession();   这样就能让你的这些代码已经写好的情况下,如果以后要扩展功能,你只需要在配置文件里添加,然后   使用   Factory.getInstace( "NewImplementationFactory ")   这种方式就可以工作了。
          Factory   instance   =   (Factory)   Class.forName(clazz).newInstance());
       
  return   instance;
      }

    public   abstract   Session   createSession();
}

还有一种情况比较常见,那就是   类库版本兼容性问题,比如   1.3   提供一个类,1.2   没有提供需要打补丁,那么可以   用   Class.forName()   运行时来探测存在版本,因为编译时并没有实际调用而是使用   Class.forName( 'xxx ').getMethod( 'name ').invoke(new   Object[])这样的方式去调用,编译通过运行时还是要确保这个方法能找到,但是给了我们一个机会:当这个方法没有找到是我们想点别的办法,而不是让   JVM   抛出   ClassNotFoundException   或   NoClassDefError   错误。     如果不用   Class.forName   那么只要这个类找不到那么程序根本没有办法运行,你没有机会控制它的流程而只有清理现场退出了。

你可能感兴趣的:(JVM,工作,thread)