java虚拟机(JVM)的类装载就是将包含在类文件中的字节码装载到java虚拟机里来,但是类装载器也不是原封不动的装载到java虚拟机,它是将(.class)文件中的内容转换成java虚拟机使用的类字节码,比如说,java程序中的字符串编译(.class)文件后是以UTF-8编码存放的,但是装载到java虚拟机后就成了Unicode编码了。当通过类装载器装载到java虚拟机中的字节码数据,就成了可执行的代码。类装载器把类装入java虚拟机中,要经过三个步骤来完成:装载,链接和初始化。
它的实现方式可以是:
1. 类名.class,例如,System.class
2. 对象.getClass(),例如,new Date().getClass()
3. Class.forName(“类名”),例如,Class.forName(“java.util.Date”);
原理:
类装载器本身也是一个java类,类库中提供了一个java.lang.ClassLoader做为类的装载器基类,也就是说真正的类装载器都必须是ClassLoader的子类。Class类中定义了一个getClassLoader方法,用于返回它所描述的类的类装载器对象,这个返回对象的类型就是ClassLoader。
一个java应用持续使用两种类型的类装载器:
1. 根装载器(bootstrap)
2. 用户定义的装载器(user-defined)
所谓根装载器(bootstrap)就是java虚拟机中内嵌的一个类,它是用特定的操作系统的本地代码实现的,它不用专门的类装载器去进行装载。它负责加载java核心包中的类(jr.jar)文件中的类。另外java核心包中还有ExtClassLoader和AppClassLoader,它们都是用java语言写的java类。
其中ExtClassLoader类装载器负责加载存放在<JAVA_HOME>/JRE/LIB/EXT目录下的jar包中的类,AppClassLoader是负责加载存放在<CLASSPATH>用户定义的类。
一个已经被父级类装载器装载的类来说,java虚拟机默认也使用这个父级类装载器去装载它所调用的其他类,由于父级类装载器不会委托子级类装载器去装载类,所以,在一般情况下,一个已被父级类装载器装载的类无法调用那些只能用被子级类装载器发现和装载的其他的类。
在设计一个类装载器的时候,应该满足以下两个条件:
对于相同的类名,类装载器所返回的对象应该是同一个类对象
如果类装载器(1)将装载类C的请求转给类装载器(2),那么对于以下的类或接口,(1)和(2)应该返回同一个类对象:a)S为C的直接超类;b)S为C的直接超接口;
下面是今天在课堂上写的文件加密:
import java.io.*;
class Fileadd
{
public static void main(String[] args)throws Exception
{
FileInputStream fin = new FileInputStream(args[0]);
FileOutputStream fout = new FileOutputStream(args[1]);
Fileadd fr = new Fileadd();
fr.jiaMi(fin,fout);
fout.close();
fin.close();
}
public void jiaMi(InputStream inss,OutputStream outss)
{
try
{
int b=0;
while((b=inss.read())!= -1)
{
outss.write((b ^ 0xff));//加密
}
outss.close();
inss.close();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
(2006.08.25)第三天学习笔记