黑马程序员_Java基础12

------- android培训java培训、期待与您交流! ----------

ClassLoader 类加载器 
系统默认的三个主要加载器:
BootStrap:加载JRE/librt.jar
ExtClassLoader:加载JRE/lib/ext/*.jar
AppClassLoader:加载CLASSPATH指定的所有jar或目录
其中BootStrap不是Java类。
所有的类加载器(除了BootStrap)都是个类,也有它的对象和Class文件
System.class.getClassLoader()为null,System的类加载器是BootStrap。
因为BootStrap不是Java虚拟机中的一个类,它是用C++编写的一个类,所以Java虚拟机无法获取它。
如类A引用了类B,Java虚拟机将用类A的加载器去加载类B.
加载器的委托机制:
每个类加载器加载类时,会先委托其父类加载器去加载
当所有祖宗类的加载器都没有加载到类,则调用发起者的类加载器加载,如果也加载不了,将抛出ClassNotFoundException,即使此加载器有子类,它也不会调用它的子类去加载。
例如:
定义一个MyServlet类继承于HttpServlet,现将MyServlet的class文件打成jar包,放到JDK的JRE/lib/ext/的路径下,则这个jar文件将由ExtClassLoader在JVM启动时进行加载,但加载这个MyServlet的同时,需要先加载他的父类HttpServlet,而这时ExtClassLoader会尝试在JRE/lib/ext/的路径下寻找HttServlet,如果没找到,则直接报错ClassNotFoundException,而不会再调用别的加载器去加载了。


可以指定某个类加载器加载类:
Class ClassLoader.loadClass(String name);
Thread类可启动一个类加载器:
Thread.setContextClassLoader(ClassLoader cl);
自定义类加载器
应用案例:自定义一个类加载器,将此加载器挂在AppClassLoader下,并且让自定义类加载器去加载某个类。
自定义ClassLoader需要继承ClassLoader抽象类,重写findClass方法,这个方法定义了ClassLoader查找class的方式。
无需覆盖loadClass(String name)
只需覆盖findClass(String name)
class MyClassLoader extends ClassLoader {
    @Override
    public Class findClass(String name) {
        byte[] b = loadClassData(name);
        return defineClass(name, b, 0, b.lenght);
    public byte[] loadClassData(String name) {
        //从指定处载入class字节码数据
        ...
    }
}

应用练习:对class文件进行加密/解密

Proxy类    动态代理技术
此类位于java.lang.reflect包下,此类拥有创建动态代理实例的方法。
构造函数:
Proxy(InvocationHandler h)
常用方法:
Class<?> getProxyClass(ClassLoader loader, class<?> ...interfaces); 根据提供的类加载器和接口数组,返回代理类的Class对象
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h); 根据提供的类加载器、接口数组和动态代理调用处理程序,返回一个动态代理实例。其内部调用了getProxyClass()方法,先创建一个动态类的Class,在绑定InvocationHandler调用处理程序,最终创建了一个动态代理对象。

创建动态代理类的实例对象:
1.通过反射获取构造函数
2.编写一个InvocationHandler实现类

InvocationHandler 接口
此接口的实现类对象是个动态代理实例的调用处理程序。
主要方法:
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
当动态代理实例调用某方法时,此调用处理程序将调用某方法的Method对象,再调用invoke方法反射执行某方法,并返回执行结果。
此被调用方法应该是被代理对象的接口中的方法。因为内部是通过那组接口反射出Method对象的。

封装获取代理对象的方法:
public static Object getProxy(final Object obj, final Advice advice) 
{
    return Proxy.newProxyInstance(
    obj.getClass().getClassLoader(), 
    obj.getClass().getInterfaces(), 
    new InvocationHandler()
    {
    @Override
    public Object invoke(Object proxy, 
    Method method, Object[] args) throws Throwable 
    {
    advice.beforeInvoke(args);
    Object retVal = method.invoke(obj, args);
    advice.afterInovoke(args);
    return retVal;
    }
    }
    );
}

应用扩展:利用动态代理的实现AOP框架

StringBuffered与StringBuilder的区别
StringBuffered是线程安全的,StringBuilder不是线程安全的。
在多线程下使用StringBuffered较好。
但是在单线程下,StrignBuilder的效率更高。

Executors类
此类常用方法:
ExecutorService newCacheThreadPool()
ExecutorService newFixedThreadPool(int size);
ExecutorService newSingleTHread()
定时器:
ScheduledExecutorService newScheduledThreadPool(int size)
ScheduledExecutorService newScheduledThreadExecutor()
ScheduledExecutorService newSingleScheduledThreadExecutor()

创建一个单线程:
ExecutorService pool = Executors.newSinghleThreadExecutor();
pool.execute(Runnable command);

内部类访问外部类的成员变量的格式: 外部类名.this.外部成员变量
随机生成1到10秒的时间:Thread.sleep(new Random().nextInt(10)+1 * 1000);

------- android培训java培训、期待与您交流! ----------

详情请查看:http://edu.youkuaiyun.com/heima

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值