黑马程序员-类加载器(class loader),黑马loader
黑马程序员-类加载器(class loader),黑马loader
------- android培训、java培训、期待与您交流! ----------
一:类加载器的概念
类加载器用来加载 Java 类到 JVM中。
Java 虚拟机使用 Java 类的方式如下:.java 文件在经过 Java 编译器编译之后就被转换成 JAVA字节码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class 类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的newInstance()方法就可以创建出该类的一个对象
二:系统中间的关系及它们之间的管辖图
注:Boot是特殊的类加载器 它不是类 当用户想得到它并且打印它的名字会得到NULL
ClassLoader loader = ClassLoaderTest.class.getClassLoader();
while (loader != null) {
System.out.println(loader.getClass().getName());
loader = loader.getParent();
}
System.out.println(loader);
结果
三:类加载器的委托机制
1>当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
首先当前线程的类加载器去加载线程中的第一个类.
如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器加载类B
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类.
2>每个类加载器加载类时,又先委托给其上级类加载器.
当所有祖宗类加载器没有加载到类,回到发起者类加载器,如果还加载不了,则抛出ClassNotFoundException异常,它不会 去找发起者类加载器的儿子,因为没有getChild()方法,即使有,有那么多的儿子交给那一个呢?所以干错就不叫给儿子处理了.
四:建立自己的类加载器(用来加密文件,解密文件)
首先加密:
public static void main(String[] args) throws Exception {
String srcPath = args[0];
String destDir = args[1];
FileInputStream fis = new FileInputStream(srcPath);
String destFileName = srcPath.substring(srcPath.lastIndexOf('\\')+1);
String destPath = destDir + "\\" + destFileName;
FileOutputStream fos = new FileOutputStream(destPath);
cypher(fis,fos);
fis.close();
fos.close();
}
/**
* 加密方法,同时也是解密方法
*/
private static void cypher(InputStream ips ,OutputStream ops) throws Exception{
int b = -1;
while((b=ips.read())!=-1){
ops.write(b ^ 0xff);//通过异或来加密文件 }
}
下面为需要加密的类
public class ClassLoaderAttachment extends Date { //为什么要继承Date待会再说? public String toString(){ return "hello,itcast"; } }
自定义进行解密的类加载器
public class MyClassLoader extends ClassLoader{
public static void main(String[] args) throws Exception {
String srcPath = args[0];
String destDir = args[1];
FileInputStream fis = new FileInputStream(srcPath);
String destFileName = srcPath.substring(srcPath.lastIndexOf('\\')+1);
String destPath = destDir + "\\" + destFileName;
FileOutputStream fos = new FileOutputStream(destPath);
cypher(fis,fos);
fis.close();
fos.close();
}
/**
* 加密方法,同时也是解密方法
*/
private static void cypher(InputStream ips ,OutputStream ops) throws Exception{
int b = -1;
while((b=ips.read())!=-1){
ops.write(b ^ 0xff);//异或一次为加密 第二次为解密 }
}
private String classDir;
protected Class<?> findClass(String name) throws ClassNotFoundException {
String classFileName = classDir + "\\" + name.substring(name.lastIndexOf('.')+1) + ".class";
try {
FileInputStream fis = new FileInputStream(classFileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
cypher(fis,bos);
fis.close();
System.out.println("aaa");
byte[] bytes = bos.toByteArray();
return defineClass(bytes, 0, bytes.length);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public MyClassLoader(){
}
public MyClassLoader(String classDir){
this.classDir = classDir;
}
}
测试运行代码:
Class clazz = new MyClassLoader("myClass").loadClass("ClassLoaderAttachment");
/*此处不能在使用ClassLoaderAttachment因为一旦用了之后,
系统的类加载器就会去加载,但是找不到因为运行时才有生成的此类,导致失败,所以该类就继承了Date类了.*/
Date date = (Date)clazz.newInstance();
System.out.println(date);
结果为
相关文章
- 暂无相关文章
用户点评