文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>java类的动态加载

java类的动态加载

时间:2010-06-10  来源:lzn_sc

(1)
JAVA中类文件加载是动态的。也就是说当我们用到的时候才会去加载,如果不用的话,就不会去加载我们的类。

JAVA为我们提供了两种动态机制。第一种是隐式机制。第二种是显示机制。如下:
两种方法:
    |
    +-- 隐式机制 :new一个对象 + 调用类的静态方法
    |
    +-- 显式机制 :
                     |
                     +-- 由 java.lang.Class的forName()方法加载
                     |
                     +-- 由 java.lang.ClassLoader的loadClass()方法加载
  (2)使用Class.forName()
Class.forName()方法具有两个形式:
            +- public static Class forName(String className)
            |
            +- public static Class forName(String className, boolean initialize,ClassLoader loader)
    参数说明:
        className - 所需类的完全限定名 (必须包含包名,否则出错!)
        initialize - 是否必须初始化类  (静态代码块的初始化)
        loader - 用于加载类的类加载器

调用只有一个参数的forName()方法等效于 Class.forName(className, true, loader)。
这两个方法,最后都要连接到原生方法forName0().
而三个参数的forName(),最后调用的是: forName0(name, initialize, loader);
  不管使用的是new 來实例化某个类、或是使用只有一个参数的Class.forName()方法,内部都隐含了“载入类 + 运行静态代码块”的步骤。 而使用具有三个参数的Class.forName()方法时,如果第二个参数为false,那么类加载器只会加载类,而不会初始化静态代码块,只有当实例化这个类的时候,静态代码块才会被初始化,静态代码块是在类第一次实例化的时候才初始化的。   (3)
直接使用类加载器
1)获得对象所属的类 : getClass()方法
2)获得该类的类加载器 : getClassLoader()方法
  (4) 实例一:
//example 2.1    
// Zoo.java

abstract class Animal {
    
    static {
    
      System.out.println("Animal static code block ");
    }
  Animal(){
    
     System.out.println("Animal constructor");
  }
}

class Tiger extends Animal {

  Tiger(){
            
    System.out.println("Tig constructor ");
  }
    
}


class Dog extends Animal {

  Dog(){
    
    System.out.println("Dog Constructor ");
  }
}



public class Zoo {

    
    public static void main(String [] args)throws Exception {
    
            System.out.println("new Zoo before");
            Zoo z = new Zoo();
            Class c = Class.forName("Dog",false,z.getClass().getClassLoader());
            System.out.println("initilize before ");
            Animal dog = (Animal)c.newInstance();
                        System.out.println("new Zoo after ");
    
    }
}
  输出如下:
[loaded Zoo from fiel:/E:/java/pritice]
new Zoo before
[loaded Animal from fiel:/E:/java/pritice]
[loaded Dog from fiel:/E:/java/pritice]
initilize before
Animal static code block
Animal constructor
Dog Constructor
new Zoo after

从 上图可以看出来类加载完成后并没有立即执行静态初始化代码,而是到了实例化的时候才进行了静态初始化。有时候我们会说静态代码是在类第一次被加载时执行 的,并且只执行一次。其实这是对与new一个对象,第一次访问类的静态代码以及第二个参数为true时而言的,对于动态的加载来说,如果 forName方法的第二个参数设置为false,那么就是在实例化的时候才会执行静态初始化。当然默认情况下第二个参数是true.

 (5)
实例二:
package test;
import java.util.Vector;
class Atest
{
  public void print()
  {
    System.out.println("use A ...");
    try {
      Class cc=Class.forName("test.Btest");
      Btest bt = (Btest)cc.newInstance();
      bt.print();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

class Btest
{
  public void print()
  {
    System.out.println("use B ...");
    
  }
}

public class Test {
  public static void main(String[] args) {
    
    //OK
    try {
      Test test=new Test();
      Class a=Class.forName("test.Atest",false,test.getClass().getClassLoader());
      System.out.println("---"+a);
      Atest aa=(Atest)a.newInstance();
      System.out.println("---"+aa);
      aa.print();
    } catch (Exception e) {
      e.printStackTrace();
    }
    
    //OK
//    try {
//      Test test=new Test();
//      ClassLoader loader=test.getClass().getClassLoader();
         //也可
//      ClassLoader loader=Test.class.getClassLoader();
//      Class a=loader.loadClass("test.Atest");
//      Atest aa=(Atest)a.newInstance();
//      System.out.println("---"+aa);
//      aa.print();
//    } catch (Exception e) {
//      e.printStackTrace();
//    }

  }
}
输出结果是: ---class test.Atest
---test.Atest@757aef
use A ...
use B ...
  可见,使用Class.forName()或ClassLoader.loadClass(),得到的只是class.如上输出.要生成对象,还须实例化.
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载