黑马程序员-(高新技术)类加载器
2015-05-09 13:40
369 查看
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
类加载器概述:
ExtClassLoader---------->JRE/lib/ext/*.jar
AppClassLoader---------->CLASSPATH指定的所有jar或目录。
这三个类加载器有继承关系:
AppClassLoader extends ExtClassLoader
extends BootStrp
并且其实类加载器也是一个java文件,也需要被别的类加载器所加载那么,最父类的类加载器是由谁加载的呢
BootStrp是直接写在jvm虚拟机中的一段程序,是由c++代码写的(感谢张孝祥老师,谢谢)
类加载器的委托机制:
当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
首先当前线程的类加载器去加载线程中的第一个类.
如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器加载类B
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类.
类加载器加载类时委托给他的上一级父类加载器,直到最顶端,由它来加载。若在最顶端的那个加载器没有加载到了类再返回到其子类加载器,再由它来执行加载,以此类推,当返回到发起者类加载器时,如果还没找到就抛出异常。
为什么委托机制要一步步抛给父类?
集中管理,如果我们写了几个类加载器,都去加载某个类,那么内存中就有多份这个类的字节码
能不能自己写一个类叫java.lang.System?
为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸优先,也就是使用的永远是爸爸的(系统的)System类,而不是我们写的System类.
类加载器示范
继承ClassLoader,覆盖findClass方法
package cn.itheima.ClassLoader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MyClassLoader extends ClassLoader {
private String dir;
public MyClassLoader() {
super();
}
public MyClassLoader(String dir) {
super();
this.dir = dir;
}
public static void main(String[] args) throws Exception {
String src = args[0];
String dest = args[1];
FileInputStream fileIn = new FileInputStream(src);
String destName = src.substring(src.lastIndexOf('\\')+1);
dest = dest+"\\"+destName;
FileOutputStream fileOut = new FileOutputStream(dest);
copy(fileIn,fileOut);
fileIn.close();
fileOut.close();
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
//通过裁剪得到一个class文件的路径
String dirPath = dir+"\\"+name.substring(name.indexOf('.')+1)+".class";
try {
FileInputStream fileIn = new FileInputStream(dirPath);
ByteArrayOutputStream buyOut = new ByteArrayOutputStream();
copy(fileIn, buyOut);
fileIn.close();//将字节反转
byte[] buy = buyOut.toByteArray();//装到数组里面
return defineClass(buy, 0, buy.length);//将字节转成class对象返回
} catch (Exception e) {
e.printStackTrace();
}
return super.findClass(name);
}
public static void copy(InputStream in, OutputStream out) throws Exception{
int b = -1;
while((b=in.read()) != -1){
out.write(b ^ 0xff);
}
}
}
package cn.itheima.ClassLoader;
public class Demo {
@Override
public String toString(){
return "hello,itcast";
}
}
package cn.itheima.ClassLoader;
public class ClassLoaderTest {
public static void main(String[] args) throws Exception {
Class clazz = new MyClassLoader("copylib").loadClass("Demo");//调用指定类加载器
Object demo = (Object)clazz.newInstance();//将加载到的烂逼类变成他的父类
System.out.println(demo.toString());
}
}
java中默认的类加载器有三个
BootStrp------>JRE/lib/rt.jarExtClassLoader---------->JRE/lib/ext/*.jar
AppClassLoader---------->CLASSPATH指定的所有jar或目录。
这三个类加载器有继承关系:
AppClassLoader extends ExtClassLoader
extends BootStrp
并且其实类加载器也是一个java文件,也需要被别的类加载器所加载那么,最父类的类加载器是由谁加载的呢
BootStrp是直接写在jvm虚拟机中的一段程序,是由c++代码写的(感谢张孝祥老师,谢谢)
当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
首先当前线程的类加载器去加载线程中的第一个类.
如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器加载类B
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类.
类加载器加载类时委托给他的上一级父类加载器,直到最顶端,由它来加载。若在最顶端的那个加载器没有加载到了类再返回到其子类加载器,再由它来执行加载,以此类推,当返回到发起者类加载器时,如果还没找到就抛出异常。
为什么委托机制要一步步抛给父类?
集中管理,如果我们写了几个类加载器,都去加载某个类,那么内存中就有多份这个类的字节码
能不能自己写一个类叫java.lang.System?
为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸优先,也就是使用的永远是爸爸的(系统的)System类,而不是我们写的System类.
继承ClassLoader,覆盖findClass方法
package cn.itheima.ClassLoader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MyClassLoader extends ClassLoader {
private String dir;
public MyClassLoader() {
super();
}
public MyClassLoader(String dir) {
super();
this.dir = dir;
}
public static void main(String[] args) throws Exception {
String src = args[0];
String dest = args[1];
FileInputStream fileIn = new FileInputStream(src);
String destName = src.substring(src.lastIndexOf('\\')+1);
dest = dest+"\\"+destName;
FileOutputStream fileOut = new FileOutputStream(dest);
copy(fileIn,fileOut);
fileIn.close();
fileOut.close();
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
//通过裁剪得到一个class文件的路径
String dirPath = dir+"\\"+name.substring(name.indexOf('.')+1)+".class";
try {
FileInputStream fileIn = new FileInputStream(dirPath);
ByteArrayOutputStream buyOut = new ByteArrayOutputStream();
copy(fileIn, buyOut);
fileIn.close();//将字节反转
byte[] buy = buyOut.toByteArray();//装到数组里面
return defineClass(buy, 0, buy.length);//将字节转成class对象返回
} catch (Exception e) {
e.printStackTrace();
}
return super.findClass(name);
}
public static void copy(InputStream in, OutputStream out) throws Exception{
int b = -1;
while((b=in.read()) != -1){
out.write(b ^ 0xff);
}
}
}
package cn.itheima.ClassLoader;
public class Demo {
@Override
public String toString(){
return "hello,itcast";
}
}
package cn.itheima.ClassLoader;
public class ClassLoaderTest {
public static void main(String[] args) throws Exception {
Class clazz = new MyClassLoader("copylib").loadClass("Demo");//调用指定类加载器
Object demo = (Object)clazz.newInstance();//将加载到的烂逼类变成他的父类
System.out.println(demo.toString());
}
}
相关文章推荐
- 黑马程序员-高新技术-内省、类加载器、代理
- 黑马程序员-java高新技术-代理和类加载器
- 黑马程序员--java高新技术 26--javaBean,泛型,类加载器,代理spring小框架
- 黑马程序员_高新技术之javaBean,注解,类加载器
- 黑马程序员--高新技术--枚举、反射、注解、类加载器、内省
- 黑马程序员 高新技术 内省、动态代理、线程池和类加载器
- 黑马程序员——高新技术——内省、注解、类加载器
- 黑马程序员——高新技术—代理类与类加载器
- 黑马程序员——高新技术--类加载器
- 黑马程序员——java高新技术-jdk1.5新特性,注解,类加载器,代理
- 黑马程序员 java高新技术<四>--类加载器、动态代理技术的深入讲解与应用
- 黑马程序员----高新技术----之JAVA泛型与类加载器
- 黑马程序员——高新技术---内省、注解、类加载器
- 黑马程序员-类加载器与委托机制(高新技术)
- 黑马程序员_高新技术:5)类加载器、代理
- 黑马程序员_高新技术之javaBean,注解,类加载器
- 黑马程序员_高新技术-内省、类加载器、代理
- 黑马程序员——Java高新技术---枚举、内省、类加载器、注解
- 黑马程序员——高新技术---类加载器、AOP
- 黑马程序员-------(高新技术)类加载器