黑马程序员 java基础加强_类加载器

来源:互联网 发布:什么是涉密网络 编辑:程序博客网 时间:2024/05/22 17:50

------- android培训、java培训、期待与您交流! ----------

1.类加载器
类加载器是将java类加载进虚拟机的class类,java虚拟机提供的三种类加载器:BootStrap,ExtClassLoader,AppClassLoader

(1).这三种加载器呈树状结构排列,最上层为BootStrp,它是jvm核心的加载器,不需要其他的java类进行加载,BootStrap加载rt.jar。
(2).ExtClassLoader加载ext目录下的java类
(3).AppClassLoader是我们最常见的类加载器,加载classpath下的java类。

2.类加载器委托机制:
每个ClassLoader本身只能分别加载特定位置和目录的类,但它们可以委托其他的类装载器去加载类,这就是类加载器的委托模式。
类加载器在加载类时会先委托他的父类进行加载:首先发起类接收到未加载过的类,会委托父类对他进行加载,从父类再到BootStrap,如果还未找到,则会一级一级往下尝试,直到某个类加载器找到了字节码文件进行加载,否则抛出异常,无法加载。

3.类初始化的五种方式
     (1)通过new关键创建实例。
     (2)调用某个类的静态方法。
     (3)访问某个类的静态属性或为其赋值。
     (4)使用反射方式强行创建Class对象。
     (5)初始化某个类的子类。 

4.注意:类加载器之间的子父类关系与一般类之间的继承关系不同,这情况和使用泛型定义的集合类似。比如Student类继承Person类,而在ArrayList<Person> l = new ArrayList<Student>();是会报错的,因为ArrayList<Peroson>和AayList<Student>之间并非继承关系。
    当一个类加载器用.getParent()方法返回null值时,要么该类加载器就是根类加载器,要么该类加载器的父类加载器是根类加载器,比如ExtClassLoader用此方法返回的就是null值。

5.自定义类加载器
       由于除了根类加载器外所有的类加载器均继承自java.lang.ClassLoader类,所以可通过继承该基类来自定义类加载器。
    ClassLoader类包含以下比较重要的方法:
   (1)loadClass(String name,boolean resolve)。
   (2)findClass(String name)。

6,自定义加加载器实例
步骤:
1.首先要明确类源文件和目标文件的路径
2.编写加密解密方法。
3.使用流对象对获取源文件,并将加密后的文件存储在另一个目录中
4.覆盖ClassLoader中的findClass方法,实现自己的类加载器
5.使用自己定义的类加载器对加密后的文件进行访问。

import java.io.*;/* * 类加载器实例 * 注意:有包名的类不能调用无包名的类 *///作为类加载器,也作为加密类public class MyClassLoader extends ClassLoader{public static void main(String[] args)throws Exception{//得到要操作的源和目标String srcPath = args[0];//System.out.println(srcPath);String destDir = args[1];String destFileName = srcPath.substring(srcPath.lastIndexOf("\\")+1);String destPath = destDir + "\\" + destFileName;//io流FileInputStream fis = new FileInputStream(srcPath);FileOutputStream fos = new FileOutputStream(destPath);//cypher methodcypher(fis,fos);fis.close();fos.close();//按照正常方式调用ClassLoaderAttachment//System.out.println(new ClassLoaderAttachment().toString());}//加密解密方法public static void cypher(InputStream ips, OutputStream ops) throws Exception{int b = -1;while((b=ips.read())!=-1){ops.write(b ^ 0xff);//异或,二进制1->0 0->1}}private String classDir;//自定义类加载器时,需要覆盖findClass方法@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) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}//定义空的构造函数public MyClassLoader(){}//定义含有name参数的构造函数public MyClassLoader(String classDir){this.classDir = classDir;}}

------- android培训、java培训、期待与您交流! ----------