您的位置:首页 > 职场人生

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

2013-09-21 14:20 441 查看
------- 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 method
cypher(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方法
@Override
protected  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 block
e.printStackTrace();
}
return null;
}

//定义空的构造函数
public MyClassLoader(){}

//定义含有name参数的构造函数
public MyClassLoader(String classDir){
this.classDir = classDir;
}
}

------- android培训java培训、期待与您交流! ----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: