黑马程序员-类加载器
来源:互联网 发布:unity3d ui界面 编辑:程序博客网 时间:2024/04/30 07:03
------- android培训、java培训、期待与您交流! ----------
类加载器:
系统默认有3个类加载器 AppClassLoader >> ExtClassLoader >> BootStrap
AppClassLoader:加载CLASSPATH指定的所有jar或目录
ExtClassLoader:加载jre/lib/ext/*.jar,加载ext下所有的jar包
BootStrap:加载jre/lib/rt.jar ,加载lib下的rt.jar。BootStrap不是java类,所以BootStrap的字节码为null,他是用C++写的一段二进制代码
Java虚拟机要加载一个类时:
首先用当前线程的类加载器去加载线程中的第一个类。
如果说这个类中还引用了其他类,那也是用加载这个类的加载器去加载。
也可以用ClassLoader.loadClass();方法来指定一个类加载器去加载。
委托机制:
类加载器在加载的时候有一个委托机制,也就是说当前加载器不会马上在自己的范围内找类加载,而是委托上级进行加载,一直委托到BootStrap,如果BootStrap在rt.jar中没找到就又一级一级的返回在其他加载器查找加载,如果返回到当前加载器也没有找到该类的话就抛出异常: ClassNotFoundException,即使当前加载器下还有加载器也不会向下查找了。
委托机制还有个一个好处就是可以保证一个类只被加载一次,如果还要去加 载的话会先根据这个委托机制上下看一看这个类被加载过没有,如果加载过 了直接返回一份字节码就是了。
自定义类加载器加密class文件:
创建一个类继承ClassLoader,创建一个加密的class文件的方法,重写finadClass方法(类加载器内部在加载类的时候是自动调用loadClass方法,而loadClass方法内部会自动的调用上级类加载器加载,以此类推,如果最后返回回来上级类加载器都没找到,则又loadClass()又调用本类的fiandClass方法,所有只重写fiandClass就行了),
public class ClassLoaderAttachment extends Date {public String toString(){return "hello,itcast heima";}}
public class MyClassLoader extends ClassLoader {public static void main(String[] args) throws Exception {//接收传入的参数 ,一个为原class文件的地址,另一个为加密后文件的地址String srcPath = args[0];String destPath = args[1] + "\\" + srcPath.substring(srcPath.lastIndexOf("\\"));//读取文件FileInputStream fis = new FileInputStream(srcPath);//写入FileOutputStream fos = new FileOutputStream(destPath);//调用加密方法,对class文件进行加密cypher(fis,fos);fis.close();fos.close();}//加密public static void cypher(InputStream is, OutputStream os) throws Exception{//System.out.println("jiami");int b = -1;while((b = is.read()) != -1){os.write(b ^ 0xff);}}private String classDir;MyClassLoader(){}MyClassLoader(String classDir){//接收地址this.classDir = classDir;}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {//拼接class文件地址name = classDir + "\\" + name + ".class";try {FileInputStream fis = new FileInputStream(name);ByteArrayOutputStream bos = new ByteArrayOutputStream();//对class文件进行解密cypher(fis,bos);fis.close();//获得字节数组byte[] buf = bos.toByteArray();bos.close();//把字节数组传入defineClass()方法 返回一个Class文件return defineClass(buf, 0, buf.length);} catch (Exception e) {e.printStackTrace();}return super.findClass(name);}}
public class ClassLoaderTest {public static void main(String[] args) throws Exception {// TODO Auto-generated method stub//使用自定义加载器加载文件//Class clazz = new MyClassLoader("bin\\test\\enhance\\classloader").loadClass("ClassLoaderAttachment");Class clazz = new MyClassLoader("itcastlib").loadClass("ClassLoaderAttachment");//这里不能用ClassLoaderAttachment类接收,因为现在classPath里的class文件是被加了密的。Date date = (Date)clazz.newInstance();System.out.println(date.getClass().getClassLoader());System.out.println(date);}}
问题:
rt.jar中有java.lang.System类,我可不可以自己再写一个java.lang.System来用?
答:rt.jar本来有System类的,而加载的时候又有委托机制,也就是说会最先找最上级,按照普通的方式的话自己写的System类是没有机会被加载到的,但是我们可以撇开委托机制,用特殊方法写一个类加载器去加载
- 黑马程序员-类加载器
- 黑马程序员-类加载器
- 黑马程序员-类加载器
- 黑马程序员-类加载器
- 黑马程序员:类加载器
- 黑马程序员--类加载器
- 黑马程序员---类加载器
- 黑马程序员-----类加载器
- 黑马程序员-----类加载器
- 黑马程序员-类加载器
- 黑马程序员-类加载器
- 黑马程序员------类加载器
- 黑马程序员-类加载器
- 黑马程序员--类加载器
- 黑马程序员---类加载器
- 黑马程序员---类加载器
- 黑马程序员-类加载器
- 黑马程序员--类加载器
- aix资源
- [翻译]ACMer 2013 Daily Training- 15th Mar for 11x&&12x
- oracle 存储过程的的参数问题
- WF4.0 入门系列(一)Hello Workflow4
- Linux C 面向连接的网络客户端实现
- 黑马程序员-类加载器
- Linux 设备驱动--- 混杂设备驱动
- emma的选择
- C# 中的委托和事件(转)
- PHP 开发环境搭建( Eclipse PDT XAMPP XDEBUG)
- 在Virtualbox上安装archlinux,使用LVM分区
- Web设计之CSS命名规范详解
- js中按指定分隔符分隔字符串
- 关于 INADDR_ANY