黑马程序员_Java基础加强4

来源:互联网 发布:淘宝网人工在线客服 编辑:程序博客网 时间:2024/05/02 04:46
---------------------- Android、Java开发期待与您交流! ----------------------

     类加载器

         类加载器负责加载类的对象,它可以在将类加载到虚拟机中的时候坚持类的完整性。

         每个程序至少拥有三个类加载器:

1.引导类加载器

2.扩展类加载器

3.系统类加载器(也称应用类加载器)

        引导类加载器负责加载系统类(通常从JAR文件rt.jar中进行加载)。它是虚拟机整体中的一部分,通常用C语言来实现。引导类加载器没有对应的ClassLoader对象,如,String.class.getClassLoader()将返回null。

       扩展类加载器用于从jre/lib/ext目录加载“标准的扩展”。可以将JAR文件放入目录,这样即使没有任何类路径,扩展类加载器也可以找到其中的各个类。

       系统类加载器用加载应用类。它由CLASSPATH环境变量或者-classpath命令行选项设置的类路径中的目录里或者JAR/ZIP文件里查找这些类

      在Sun公司的Java语言实现中,扩展类加载器和系统类加载器都是Java来实现的。它们都是URLClassLoader类的实例

警告:如果JAR文件放入jre/lib/ext目录中,并且在它的类中有一个类需要调用系统类或者扩展类,那么就会遇到麻烦。扩展类加载器并不使用类路径。在使用扩展目录来解决类文件的冲突之前,要牢记这种情况

注意:除了所有已经提到的位置,还可以从jre/lib/endorsed目录中加载。这种机制只能用于将某个标准的Java类库替换为更新的版本(例如那些支持XML和CORBA的类)

类加载器的层次结构

        类加载器有一种父/子关系。除了引导类加载器外,每个类加载器都有一个父类加载器。根据规定,类加载器会为它的父类加载器提供一个机会,以便加载任何给定的类,并且只有在其父类加载器加载失败时,它才会加载该给定类。例如,当要求系统类加载器加载一个系统类(比如,java.util.ArrayList)时,它首先要求扩展类加载器进行加载,扩展类加载器则首先要求引导类加载器进行加载。引导类加载器查找并加载rt.jar中的这个类,而无须其他类加载器做更多的搜索

自定义类加载器

       需要继承ClassLoader类并重写父类findClass(String className)方法。

      ClassLoader超类的loadClass方法用于将该类的加载操作委托给其父类加载器去进行,只有当该类尚未加载并且父类加载器也无法加载该类时,才调用findClass方法

      如果要实现该方法,要做到以下几点:

1.为来自本地文件系统或者其它来源的类加载其字节码

2.调用ClassLoader超类的defineClass方法,向虚拟机提供字节码


常用方法:

java.lang.Class

         ClassLoader  getClassLoader():返回该类的类加载器,如果父类是引导类加载器则返回null

java.lang.ClassLoader

         protected Class defineClass(String name,byte[] b,int off,int len):将一个 byte 数组转换为Class 类的实例。

         protected Class findClass(String name):使用指定的二进制名称查找类

         InputStream getResourceAsStream(String filePath):返回读取指定资源的输入流。

        static  ClassLoader  getSystemClassLoader():返回委托的系统类加载器。

import java.util.Date;public class ClassLoaderAttachment extends Date {private static final long serialVersionUID = 1L;public String toString() {return "hello itcast!";}}

import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;/** * 自定义类加载器类 * @author wxd * */public class MyClassLoader extends ClassLoader {private String classDir;public MyClassLoader() {}public MyClassLoader(String classDir) {this.classDir = classDir;}public static void cypher(InputStream ips, OutputStream ops)throws IOException {int b = -1;while ((b = ips.read()) != -1) {ops.write(b);}ips.close();ops.close();}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {String classFileName = classDir + "\\" + name+".class";try {FileInputStream fis = new FileInputStream(classFileName);ByteArrayOutputStream bos = new ByteArrayOutputStream();cypher(fis, bos);fis.close();byte[] bytes = bos.toByteArray();return defineClass(bytes, 0, bytes.length);} catch (Exception e) {}System.out.println("classFileName:" + classFileName);return super.findClass(classFileName);}}

import java.util.Date;public class ClassLoaderTest {@SuppressWarnings("rawtypes")public static void main(String[] args) throws Exception {System.out.println(ClassLoaderTest.class.getClassLoader().getClass().getName());System.out.println(System.class.getClassLoader());ClassLoader loader = ClassLoaderTest.class.getClassLoader();while (loader != null) {System.out.println(loader.getClass().getName());loader = loader.getParent();}System.out.println("loader:" + loader);Class clazz =new MyClassLoader("itcastlib").loadClass("ClassLoaderAttachment");Date date = (Date) clazz.newInstance();System.out.println("date:"+date);}}


---------------------- Android、Java开发期待与您交流! ----------------------
0 0
原创粉丝点击