----------------------android培训、java培训、期待与您交流! ----------------------
一. 类加载器
1.类加载器基础知识
类加载器的作用就是获取.class里面的内容等等
java虚拟机中的三个类加载器:BootStrap,ExtClassLoader,AppClassLoader
类加载器也是java类,因为其他是java类的类加载器本身也是要被类加载器加载的,只有BootStrap不是java类,它嵌套在java虚拟机的内核中。
2.类加载器之间的父子关系和管辖范围
3.类加载器的委托机制
当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?首先当前线程的类加载器去加载线程中的第一个类。
如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
每个类加载器加载类时,又先委托给其上级类加载器。
当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有getChild方法,即使有,那有多个儿子,找哪一个呢?
对着类加载器的层次结构图和委托加载原理,解释先前将ClassLoaderTest输出成jre/lib/ext目录下的itcast.jar包中后,运行结果为ExtClassLoader的原因。
加载类的方式:
一、用当前线程的类加载器加载了线程中的第一个类,然后这个类引用到的其他类,那么那个类也用这个线程的这个类加载器进行加载。
二、可以直接调用ClassLoader.loadClass()方法来指定某个类加载器加载类。
三、每个类加载器加载类的时候,会先委托给上级类加载器,会从BootStrap开始查看这个类是否已经加载过,如果父类加载器没有加载过这个类,那么才会顺着继承关系逐级下来进行查看。
可以写一个java.lang.String类通过自己写的类加载器加载,但是这个类加载器就不是依托与虚拟机加载类了。因为如果依托于java虚拟机加载的话,java虚拟机中的类加载机制是委托机制,即最后会从BootStrap开始逐级查找要进行加载的类,如果在父类中先找到了这个类,java虚拟机就会加载这个类,那么我们写的这个类就根本不可能加载到。
数组类的
4.
自定义的类加载器必须继承ClassLoader
模板方法设计模式:loadClass:通过findClass方法按照委托机制查找对应的类,在通过父类加载器检查所请求的类后,如果找到了类,那么就立刻调用defineClass把找到的字节码转换为这个类的实例。如果经过父类的加载器检查所请求的类却没有找到,反而在自定义的类加载器中找到了这个类,那么就会通过自定义的类加载器中复写过的findClass来对类的字节码进行在操作,然后调用defineClass把找到的字节码转换为这个类的实例。
A.
Class<?>
protected
B.
protected
例子:
package com.base.chapter4;
class Base{
public static int a = 10;
public int b = 20;
static
{
System.out.println("Static Init Base " + a);
//System.out.println("Null Init " + b);
}
public Base()
{
System.out.println("Init Base " + this.b);
}
}
class SuperClass extends Base{
//静态变量、静态块执行顺序,按书写先后顺序
public static int a1 = getSuperStaticNumber();
public int b1 = getSuperInstanceNumber();
public SuperClass()
{
System.out.println("Init SuperClass" + this.b1);
}
static
{
System.out.println("Static Init SuperClass" + a1);
}
public static int getSuperStaticNumber()
{
System.out.println("Static member init");
return 100;
}
public int getSuperInstanceNumber()
{
System.out.println("Instance member init");
return 200;
}
}
public class Sub extends SuperClass{
public static int a2 = getStaticNumber();
public int b2 = getInstanceNumber();
public Sub()
{
System.out.println("Init SubClass " + this.b2);
}
public static int getStaticNumber()
{
System.out.println("Static member init Sub");
return 1000;
}
public int getInstanceNumber()
{
System.out.println("Instance member init Sub");
return 2000;
}
static
{
System.out.println("Static Init " + a2);
}
public static void main(String args[])
{
new Sub();
}
}
结果:
Static Init Base 10
Static member init
Static Init SuperClass100
Static member init Sub
Static Init 1000
Init Base 20
Instance member init
Init SuperClass200
Instance member init Sub
Init SubClass 2000
二。代理
AOP(Aspect
1.proxy类:
构造方法:
protected
方法:
static
static
static
static
2.InvocationHandler接口
3.创建动态代理类的方法
以Collection接口的动态代理类为例
A.使用Proxy.getProxyClass(ClassLoader
Collection
public
})
B.使用Proxy.newProxyInstance(ClassLoader
Collection
public
})
怎样将目标类传入代理的Invoke方法中?
把target和系统代码[即我们要在方法前或后面执行的代码]封装成对象,抽到InvocationHandler外面,之后通过参数的方法传递进去。getProxy(tarket,advice)
InvocationHandler类里面只复写了Object里面的equals,toString,hashCode方法。没有复写getClass方法,所以想要获取代理类代理的目标的类名是需要自己复写getClass方法的。
代理的运作其实还是用到了反射的原理。
C.
protected
protected
protected
D.
protected
protected
---------------------- android培训、java培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net/heima