黑马程序员-张老师加强6-类加载器

类加载器:

基本概念:

一般来说:java文件(源程序)经过编译器被转换成java字节码。类加载器负责读取字节码文件,并转换成java.lang.class的一个实例对象。每个这样的实例代表一个java类。通过实例的newInstance方法,就可以创建出该类一个对象。

Java.lang.ClassLoader类的介绍:

ClassLoader类的基本职责就是根据指定的类的名称,找到或生产对应的字节码,然后从这些字节码中定义出一个java类。即,java.lang.Class的一个实例。

常用方法:

LoadClass(String name);加载名称为name的类,返回结果是java.lang.Class的实例

findClass(String
name):查找名称为name的已经被加载过的类,返回ava.lang.Class的实例。

defineClass(String name,byte[] b,int
off,int,len);将字节数组b转成java类。

Java默认三个主要类加载器:

BootStrap,ExtClassLoader,AppClassLoader

BootStrap:用于加载其他类加载器。

类加载器之间的父子关系和管辖范围图

加载器的委托机制:

  每个类加载器加载类时,又先委托给其上级类加载器。(避免出现多字解码现象) 这就是委托机制。

问:当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?

  如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。
但是类加器要去找上级的类加载,然后再找上一级累加器,

如果找不到,则返回发起者。发起者如果也找不到,则报异常,不会再找下一级。

自定义类加器步骤:

  继承ClassLoader类。

  复写findclass(String);

自定义类加载器的加载过程:

  1.调用 findLoadedClass(String)
来检查是否已经加载类

  2.委托给父类加载器,父类加载器调用loadClass
方法

  3.loadClass调用调用 findClass(String)
方法查找类。

  4.如果找不到,发起者再找。

如何实现父类加载器查找不到我们的文件呢?

  类加载器必须在它字节的目录下才能加载。我们可以控制类文件存放的目录。


package cn.itcast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class DemoCLassLoader extends ClassLoader{
public static void main(String[] args) throws Exception {
String resPath = args[0];//需要被加密的文件。args[0]=D:\javaxue学习\test\src\cn\itcast\ClassLoaderDemo.java
// String desPath = args[1];//加密后的文件存方法的路径名。
File file = new File(resPath);
if(!file.exists()){throw new RuntimeException("文件不存在");}
FileInputStream in = new FileInputStream(file);
System.out.println("‘fa");
//将加载后的文件扔保存到resPath的路径下。
int index = resPath.lastIndexOf("\\")+1;
String filepath = resPath.substring(0,index);//获取路径名
File file1 = new File(filepath+"加密"+".class");//加密后存储文件。
System.out.println(file1);
FileOutputStream os= new FileOutputStream(file1);
cypher(in,os);
}
//加密
public static void cypher(InputStream in,OutputStream os) throws Exception{
int len = -1;
while((len=in.read())!=-1){
os.write(len&255);
}
in.close();
os.close();
}

//要加载的文件的路径
public DemoCLassLoader() {
}
private String dir;
public DemoCLassLoader(String dir) {
this.dir=dir;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
//使用类加载器并解密 :name是要加载的文件的名字
try {
String path = dir+name+".class";
FileInputStream fis = new FileInputStream(path);
//创建缓存
ByteArrayOutputStream fos = new ByteArrayOutputStream();
cypher(fis,fos);
byte[] buf = fos.toByteArray();
//创建实例对象
System.out.println(new String(buf, 0, buf.length));
return defineClass(buf, 0, buf.length);
}
catch (Exception e) {
e.printStackTrace();
}
return super.findClass(name);
}
}

黑马程序员-张老师加强6-类加载器,布布扣,bubuko.com

时间: 2024-10-10 14:48:01

黑马程序员-张老师加强6-类加载器的相关文章

黑马程序员—张老师基础加强7-动态代理

代理: 要为已经存在的多个具有相同接口的目标类的各个方法增加一些系统功能. 例如:异常处理,日志和计算方法的运行时间,事物管理等,怎么做 如 在运行前后增加计算时间的方法.show(){ sop(); } 编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码. 动态代理: 要为系统中的各种接口的类增加代理功能,那需要太多代理类. jvm可以在运行期间动态生成出类的字节码,这种动态生成的类往往被调用作代理类, 即动态代理类. jvm生成动态类

黑马程序员-张老师基础5-泛型

泛型: 泛型只是提供给编译器.在编译完之后,生产字节码文件时就擦除类型信息,<>泛型就不在了 泛型的术语: 整个Arraylist<E>:称为泛型类型. Arraylist<E>中的E称为类型变量或类型参数 整个Arraylisst<Integer>称为:参数化的类型 Arraylist<Integer>中的Integer称为类型参数的实例. Arraylist<Integer>中的<>是typeof Arraylist称

黑马程序员-张老师基础加强4-注解

注解: 注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事.标记可以加在包,类,字段,方法,方法的参数以及局部变量上. 注解: @interface A{ } 应用了注解的类: @ class B{ } 对应用了注解的类记性反射操作 class C{ B.class.isAnnotionPresent(A.class); A a = B.

黑马程序员——【Java高新技术】——类加载器

一.概述 (一)类加载器(class loader) 用来动态加载Java类的工具,它本身也是Java类. (二)类加载器作用 负责加载 Java 类的字节代码到 Java 虚拟机中. (三)Java类加载器 1.Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类加载器负责加载特定位置的类: (1)BootStrap(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader.

黑马程序员-张老师基础加强3-内省

内省:javaBean JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则. JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量.如果方法名为setId,中文意思即为设置id,去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的. 一.setId()的属性名?id 二.isLast()的属性名?last 三.setCPU的

黑马程序员——类加载器初识

java类加载器就是将生成的字节码加入到内存中. java类加载器也是类,它们是由最原始的类加载器加入到java虚拟机中,然后再由他们加载其他的类,而最原始的类加载器就是BootStrap,他不是Java类,是由C++编写的 在java中有三种类加载器:BootStrap(加载系统类,如System),ExtClassloader(加载lib/ext/里的.jar包),AppClassLoader(加载我们自定义的类) BootStrap是ExtClassLoader的上级,ExtClassLo

黑马程序员_类加载机制

------- android培训.java培训.期待与您交流! ---------- 0.类加载机制知识体系 1.类与JVM进程 使用Java命令运行某个Java程序时,此命令会启动一个Java虚拟机进程,不管Java程序多复杂,开启了多少个线程,这个线程都运行在Java虚拟机进程里.同一个JVM的所有线程.所有变量都处于同一个进程里,都使用该JVM进程的内存区. 只有出现下列情况时,JVM进程才会终止: 1)程序正常结束. 2)程序执行到代码System.exit()或Runtime.get

黑马程序员——自定义类加载器

自定义类加载器是在是血的不怎明白 这里只学会了一个简单的加密解密方法 //定义一个加密方法 public static void md(InputStream inputStream,OutputStream outputStream) throws Exception{  int b = 0;  while((b = inputStream.read())!=-1){   //使用^异或,相同的为0,不同的为1,由于0xff是255,后八位都是1,   //这样就将原来的1变成了0,0变成了1

黑马程序员——基础加强篇

------- android培训.java培训.期待与您交流! ---------- MyEclipse相关知识 Workspace与project 切换工作空间:File---Switch Workspace---Other 一个工作间包含多个工程,切换工作间之后,会影响里面的工程,例如快捷键什么的都要重新配置如果重新配了之后快捷键还没有用就要考虑下那个快捷键是不是冲突了    视图管理与程序调试 可以通过Window---Show View来添加各种透视图. 调试程序的时候可以在代码右边双