类加载器是将硬盘上class文件加载到内存中的一个机制。
三个主要类加载器是BootTrap,ExtClassLoad,AppClassLoad。
其中,BootTrap是java虚拟机中内核的加载器,而不是java类。
类加载器采用具有父子关系的树形结构进行组织,ExtClassLoad是BootTrap的儿子,AppClassLad是ExtClassLoad的儿子。
每个类加载器都有自己的作用域,BootTrap是JRE/lib/rt.jar
ExtClassLoad是JRE/lib/ext/*.jar
AppClassLoad是ClassPath指定的所有jar或目录
当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
首先当前线程的类加载器去加载线程中的第一个类。
如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
每个类加载器加载类时,又先委托给其上级类加载器。
动态代理是相对于静态代理而言的
动态代理和静态代理的区别
静态代理类由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:在程序运行时,运用反射机制动态创建而成。
下面是动态代理类的代码,有一些我自己的想法:
- package ClassTest;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.util.ArrayList;
- import java.util.List;
- public class ProxyHarvest {
- public static void main(String[] args) {
- /*
- * 1.动态代理类不可能用到目标类所有的方法,因为目标类本身有自己的特有方法。而动态代理类只能强转成接口的类型,所以有些目标类的方法不能调用到。
- 2.在动态代理类强转成某“一个”接口类型时,只能用到目标类这个接口中所有的方法,而不能用到其他接口中的方法。
- */
- String al=new String("1");
- InvocationHandlerInterface h=new InvocationHandlerInterface(al);
- CharSequence str=(CharSequence)Proxy.newProxyInstance(al.getClass().getClassLoader(),
- al.getClass().getInterfaces(),
- h);
- System.out.println(str);
-
- }
- }
- class InvocationHandlerInterface implements InvocationHandler{
- private Object obj;
- public InvocationHandlerInterface(Object obj) {
- this.obj=obj;
- }
- public Object getProxy(){
- return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),this);
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- System.out.println("jhaha");
- return method.invoke(obj, args);
- }
-
- }
复制代码
|