zoukankan      html  css  js  c++  java
  • Java类加载文章1(z)

    1. JAVA类装载器在装载类的时候是按需加载的,只有当一个类要使用(使用new 关键字来实例化一个类)的时候,类加载器才会加载这    个类并初始化。
        类Main:
       
    java 代码
    1. public class Main {  
    2.     public static void main(String[] args) {  
    3.          A a = new A();  
    4.          a.print();  
    5.          B b = new B();  
    6.          b.print();  
    7.      }  
    8. }  
      
    类A:
    java 代码
    1. public class A   {  
    2.     public void print() {  
    3.          System.out.println("Using Class A");  
    4.      }  
    5. }  

    类B:
    java 代码
    1. public class B {  
    2.     public void print() {  
    3.          System.out.println("Using Class B");  
    4.      }  
    5. }  

    执行:java -varbose:class Main
    执行结果:
        E:\DEV>java -verbose:class Main
        [Opened C:\Program Files\Java\jre1.5.0_11\lib\rt.jar] (类装载器会首先加载rt.jar加载基础类)
        .
        .
        [Loaded Main from file:/E:/DEV/] (类装载器载入相应类并初始化)
        [Loaded A from file:/E:/DEV/]
        Using Class A
        [Loaded B from file:/E:/DEV/]
        Using Class B
    2. 让JAVA程序具有动态性
       使用显式方式来实现动态性,我们需要自己动手处理类载入时的细节部分。

         两种方法:
        |
        +-- 隐式的 : 使用new关键字让类加载器按需求载入所需的类
        |
        +-- 显式的 :
                   |
                         +-- 由 java.lang.Class的forName()方法加载
                         |
                   +-- 由 java.lang.ClassLoader的loadClass()方法加载

        (1) 使用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(),其定义如下:
    private static native Class forName0(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException;
    只有一个参数的forName()方法,最后调用的是:
    forName0(className, true, ClassLoader.getCallerClassLoader());
    而三个参数的forName(),最后调用的是:
    forName0(name, initialize, loader);
    所以,不管使用的是new 來实例化某个类、或是使用只有一个参数的Class.forName()方法,内部都隐含了“载入类 + 运行静态代码块”的步骤。而使用具有三个参数的Class.forName()方法时,如果第二个参数为false,那么类加载器只会加载类,而不会初始化静态代码块,只有当实例化这个类的时候,静态代码块才会被初始化,静态代码块是在类第一次实例化的时候才初始化的。

        (2) 直接使用类加载器
           +— 获得对象所属的类 : getClass()方法
               |
               +— 获得该类的类加载器 : getClassLoader()方法
    java 代码
    1. public class Main3 {  
    2.     public static void main(String[] args) throws Exception {  
    3.          Main3 main3 = new Main3();  
    4.          System.out.println("准备载入类");  
    5.          ClassLoader loader = main3.getClass().getClassLoader();  
    6.          Class clazzA = loader.loadClass(args[0]);  
    7.          System.out.println("实例化类A");  
    8.          A o1 = (A) clazzA.newInstance();          
    9.      }  
    10. }  

    3 类加载器的层次
  • 相关阅读:
    JSP和Servlet的相同点和不同点、有何联系。
    Java泛型
    HttpURLConnection与HttpClient比较和使用示例
    Mybatis中的#和$的区别
    MySQL_第三方数据库引擎_tokudb
    mysql的并发处理机制_上篇
    SQL SERVER 自动生成 MySQL 表结构及索引 的建表SQL
    SQL SERVER大话存储结构(6)_数据库数据文件
    SQL SERVER大话存储结构(4)_复合索引与包含索引
    基于binlog来分析mysql的行记录修改情况(python脚本分析)
  • 原文地址:https://www.cnblogs.com/macula7/p/1960543.html
Copyright © 2011-2022 走看看