1. 类加载器及其委托机制
java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器每个负责加载特定位置的类:
BootStrap(不是java类,0层,JRE/lib/rt.jar),ExtClassLoader(一层,jre/lib/ext/*.jar),AppClassLoader(二层,ClassPath指定的所以jar或者目录),加载每一个类的方法都是由顶级往下查找。比如自定义一个java.lang.System类,由AppClassLoader发起,就会传递到最上层的BootStrap先进查找,就能找到java.lang.System类,下层的加载器就不会在去加载,所以自定义的java.lang.System类是不能加载到虚拟机的。如果不是java.lang.System类,是一个BootStrap加载器和ExtClassLoader都加载不到的,在AppClassLoader查找完后就停止查找,没找到报异常。
自定义类加载器编写原理:
自定义类加载器必须继承ClassLoader
重写findClass方法
2. 动态类
创建动态类及查看方法列表:
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy1.getName());
System.out.println("----------begin constructors list----------");
/*$Proxy0()
$Proxy0(InvocationHandler,int)*/
Constructor[] constructors = clazzProxy1.getConstructors();
for(Constructor constructor : constructors){
String name = constructor.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = constructor.getParameterTypes();
for(Class clazzParam : clazzParams){
sBuilder.append(clazzParam.getName()).append(',');
}
if(clazzParams!=null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
System.out.println("----------begin methods list----------");
/*$Proxy0()
$Proxy0(InvocationHandler,int)*/
Method[] methods = clazzProxy1.getMethods();
for(Method method : methods){
String name = method.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = method.getParameterTypes();
for(Class clazzParam : clazzParams){
sBuilder.append(clazzParam.getName()).append(',');
}
if(clazzParams!=null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
}
创建动态类的实例对象及调用方法:
System.out.println("----------begin create instance object----------");
//Object obj = clazzProxy1.newInstance();
Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);
class MyInvocationHander1 implements InvocationHandler{
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}
// proxy1为空
Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHander1());
System.out.println(proxy1);
proxy1.clear();