自定义泛型类的应用:
为了统一类中的方法的类型,我们可以不定义各个方法的泛型,而在这些方法所在的类定义泛型
如果类的实例对象中的多处都要用到同一个泛型参数,即这些地方引用的泛型类型要保持同一个实际类型时,这时候就要采用泛型类型的方式进行定义,也就是类级别的泛型。
在对泛型类型进行参数化时,类型参数的实例化别蓄势引用类型,而不能是基本类型。
当一个变量被声明为泛型时,只能被实例变量和方法调用,而不能被静态变量和静态方法调用。静态成员时被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。
通过反射获得泛型的实际类型参数:
通过一个变量是没办法知道自己是什么泛型类型的,但把这个变量传给一个方法使用后,方法是可以知道变量的泛型类型的,可以通过反射的方法来获得变量的泛型类型。
类加载器:
java虚拟机中可以安装多个加载器,系统默认的三个主要类加载器,每个类负责加载特定位置的类:
BootStrap—————JRE/lib/rt.jar
ExtClassLoader————JRE/Lib/ext/*.jar
AppClassLoader————CLASSPATH指定的所有jar或目录
类加载器也是Java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有一个类加载器不是Java类,这就是BootStrap,由C++编写。
类加载器的委托机制:
当Java虚拟机要加载一个类时,选择类加载器的方法:
首先当前线程的类加载器去加载线程中的第一个类,
如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器来加载类B,
还可以调用ClassLoader.loadClass()方法来指定某个类加载器来加载某个类。
每个类加载器加载类时,又先委托给其上级类加载器。当最上级加载器找不到类时再逐级调用下一级加载器。
编写自己的类加载器:
自定义的类加载器必须继承ClassLoader
需要了解loadClass方法,findClass方法,defineClass方法。
编写步骤:
编写一个对文件内容进行简单加密的程序,
编写一个自己的类加载器,实现对加密过的类进行装载和解密,
编写一个程序调用类加载器加载类,在原程序中不能用该类名定义引用变量,因为编译器无法识别这个类。
程序中可以除了使用classloader.load方法以外,还可以使用设置线程上下文类加载器或者系统类加载器,然后再使用class.forMame。
APO:
面向方面编程。系统中存在交叉业务,一个交叉业务就是要切入到系统中的一个方面,即为AOP。
AOP的目标就是要使交叉业务模块化,可以采用将切面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果相同。
代理技术可以很好的解决这种问题,是实现AOP功能的核心和关键技术。
动态代理技术:
JVM可以在运行期动态生成出类的字节码,这种动态生成的类被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库(目前开源,也许将来会加到jdk中)可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码。
a。在调用目标方法之前。
b。在调用目标方法之前。
c。在调用目标方法前后。
d。在处理目标方法异常的catch块中。
创建动态类的实例对象:
首先用反射获得构造方法。
编写一个最简单的invocationhandler类
调用构造方法创建动态类的实例对象,并将编写的invocationhandler类的实例对象传进去。
JVM创建动态类所需信息:
生成的类中有哪些方法,通过让其实现哪些接口的方式进行告知。
产生的类的字节码必须有一个关联的类加载器对象。
生成的类中的方法的代码,我们把代码写在一个约定好的接口对象的方法中,把对象传给他,它调用我们的方法,即插入了我们的代码。
提供执行代码的对象就是那个invocationhandler对象,是在创建动态类的实例对象的构造方法时传进去的。
也可以用Proxy.newinstance方法直接一步就创建出代理对象。