JAVA反射技术(二)
一、ClassLoader初步
? ? 类加载器负责加载所有的类,系统为所有被载入内存中的类生成一个java.lang.Class实例。一旦一个类被载入到JVM中,同一个类就不会再次被载入了,这是针对同一个加载器,不同的加载器还是可以加载同一个类的,不同加载器加载同一个类在JVM中是不同的。因为在JVM中用类的全限定类名加类加载器作为其唯一标识。
? ? 在JVM启动时,会形成有三个类加载器组成的初始类加载器层次结构:
? ? -->Bootstrap ClassLoader:根类加载器
? ? -->Extension ClassLoader:扩展类加载器
? ? -->System ClassLoader:系统类加载器
?
? ? Bootstrap ClassLoader是使用C++写的,我们是无法得到他的,他是java的核心Loader,比如我们通过String.class.getClassLoader()是获得不到他的名字的,返回的是空值。
? ?如果父类加载器加载了某个类,子类就不会加载了。
? ?ClassLoader动态加载:
? ? a.并非一次性加载
? ? b.需要运行时才加载
? ? c.可以观察类的具体加载过程:java -verbose:class ?在eclipse中只要配置后面的-verbose:class
? ? d.static语句块在加载后执行一次。
? ? e.dynamic语句块每次new新的对象都会执行
? ? ? ? 等同于构造方法中的语句。
? ? ? ? 用的比较少。
具体看参见:http://gzcj.iteye.com/blog/394644
?
二、使用反射实现JDK动态代理
? ? 在java中提供了Proxy类和一个InvocationHandler接口,通过他们俩我们就可以创建JDK动态代理,下面让我们通过一个实例来看看如何使用吧:
Person接口package com.lyl.reflect;public interface Person {void walk();void sayHello(String name);}
?
MyInvocationHandler.javapackage com.lyl.reflect;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("正在运行的方法:"+method);if(args!=null){System.out.println("执行该方法传入的参数:");for(Object arg:args){System.out.println(arg);}}else {System.out.println("该方法没有传入参数!");}return null;}}
?
ProxyTest.javapackage com.lyl.reflect;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class ProxyTest {public static void main(String[] args) {InvocationHandler handler=new MyInvocationHandler();//返回Person接口的代理类实例Person person=(Person)Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, handler);person.walk();person.sayHello("ITEYE");}}
?通过Proxy类的newProxyInstance()方法我们可以获得一个指定接口的代理类实例,在MyInvocationHandler中会自动执行invoke方法,执行结果如下:
正在运行的方法:public abstract void com.lyl.reflect.Person.walk()该方法没有传入参数!正在运行的方法:public abstract void com.lyl.reflect.Person.sayHello(java.lang.String)执行该方法传入的参数:ITEYE?