JAVA基础加强_高新技术_收获六

时间:2022-01-16 15:42:31


JAVA基础加强_高新技术_收获六

java 高级视频教程_网络编程 41.avi-56.avi

自定义泛型方法的练习与类型推断总结:

编译器判断泛型方法的时机类型参数的过程称为过程类型判断,类型推断相当于知觉推断的,其实现方法是一种非常复杂的过程。
方法返回类型不确定,或参数类型不确定,则定义泛型的方法。
泛型方法前面返回值之前用<T>说明类型,就为泛型方法。
之后传的什么类型,实际就是什么类型。

根据调用反省方法时时机传递的参数类型或返回值的类型来推断,具体规则如下:
1、当某个类型变量只在整个参数列表中的所有参数和返回值中一处被应用了,那么根据调用方法时该处的实际应用类型来确定,这很容易凭感觉推断出来,及时直接根据调用方法是传递的参数类型或返回值来决定泛型参数的类型,例如:
swap(new String[3],3,4)-->static <E> void swap(E[] a,int i,int j)
2、当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法是这多处的实际应用类型都对应同一种类型来确定,这很容易凭着感觉推断出来,例如:
add(3,5) --> static <T> add(T a,T b)
3、当某个类型变量在整个参数列表中的所有参数和返回值中多处被应用了,如果调用方法是这多处的实际应用类型对应到了不同的类型,切没有使用返回值,这时候区多个参数中的最大交集类型,例如,下面的语句实际对应的类型就是Number了,编译没问题,只是运行时出问题:
fill(new Integer[3],3.5f) --> static <T> void fill(T[] a,T v)
4、当某个类型变量在整个参数类型列表中的所有参数和返回值中的多数被应用了,如果调用方法是这多处的实际应用类型对应到了不同的类型,并且使用返回值,这时候有限考虑返回值的类型,例如,下面语句实际对应的类型就是Integer了,编译器将报告错误,将变量x的类型改为float,对比eclipse报告的错误提示,接着再将变量x类型改为Number,则没有了错误:
int x(3,3.5f) static <T> T add(T a,T b)

自定义泛型类的应用:
Dao缩写——data acess object-->crud 对数据库的增删改查 creat、read、update、delete

如果类的实例对象中多处都要用到一个泛型参数,即这些地方引用的泛型类型要保持同一个实际类型是,这时候就要采用泛型类型的方式进行定义,也就是类级别的泛型语法如下:

下面的方法可以对传进来什么类和返回什么类。
public class GenericDao<T>{
    public void add(E x){
    }
    public E findById(int id){
    }
    public void delete(T obj){
    }
    public void delete(int id){
    }
    public void update(T obj){
    }
    public Set<T> findByConditions(String where){
        return null;
    }
    ........
}
在用的时候需要指定对应类型——类级别的泛型是i根据引用该类名时指定的类型信息来参数化类型变量的。
GenericDao<ReflectPoint> dao= new GenericDao<ReflectPoint>();

在泛型类型中需注意事宜:
1、在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。
2、当一个变量被声明为泛型时,只能被实例变量和方法调用(还有内嵌类型),而不能被静态变量和静态方法调用。因为静态成员是被所有参数化的类共享的,所以静态成员不应该有类级别的类型参数。


通过反射获得泛型的实际类型参数:
---------------
需要再次看视频总结
---------------

类加载器及其委托机制的深入分析:
java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个负责加载特定位置的类:
加载器名:BootStrap、ExtClassLoader、AppClassLoader
对应管辖范围:JRE/lib/rt.jar、Jre/lib/ext/*.jar、CLASSPATH指定目录的所有jar或目录
类加载器也是java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是java类,这正是BootStrap。

java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类的装载器对象时,需要为其制定一个父级类装载器对象或默认采用系统类装载器为其父类加载。

类加载器的委托机制:
当java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
1、首先当线程的类加载器去加载线程中的第一个类。
2、如果类A中引用的类B,java虚拟机将使用加载类A的类装载器来加载类B。
3、还可以直接调用ClassLoader.loadClass()方法来指定某个加载器去加载某个类。

每个类加载器加载类时,又先委托给其上级类加载器。
当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛出ClassNotFoundException,不是再取找发起者类加载器的儿子,因为没有getChild方法,即使有,那有多少儿子,找哪个呢?



自定义类加载器的编写原理分析:
写自己的类加载器,字节的类加载器覆盖findClass(),就可以获取到对应的字节码,将这些字节码交给definClass()方法将其变成Class对象。

模板方法设计模式
父类-->loadClass/findClass()/得到Class文件转换成字节码-->definClass()把自己数组变成Class
子类1(自己干)
子类2(自己干)
总体流程在父类规定好,子类继承父类方法,父类定义局部细节为抽象方法,子类填写对应抽象方法,流程在父类中已经规定好。



编写对class文件进行加密的工具类:
编写和测试自己编写的解密类加载器:
类加载器的一个高级问题的实验分析:
---------------
需再次总结
---------------


分析代理类的作用与原理及AOP概念:

什么是代理:
要为已存在的多个具有相同接口的目标类各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、实物管理、等等。
代理原理可以理解为,
代理类(代理类中的方法为调用目标类中方法并扩展)和目标类实现同一个接口,客户端调用程序直接对接口操作。

AOP(Aspect Oriented Program面向方面的变成):
交叉业务:安全、实物、日志等功能要贯穿到好多个模块中。
AOP的目标就是要使交叉业务模块化,可以采用将切面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果一样。

动态代理技术:
JVM可以在运行期动态生成出类的字节码,这种动态生成类旺旺被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以JVM生成的动态类只能用作具有相同接口的目标类和代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标和相应方法对外返回目标返回结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1、在调用目标方法之前
2、在调用目标方法之后
3、在调用目标方法前后
4、在处理目标方法异常的catch块中


创建动态类及查看其方法列表信息:
创建动态类的实例对象及调用其方法:
完成InvocationHandler对象的内部功能:
分析InvocationHandler对象的运行原理:
动态类生成的类实现了Collection接口(可以实现若干接口),生成的类有Collection接口中的所有方法和一个如下接受InvocationHandler参数的构造方法。
总结分析动态代理类的设计原理与结构:
运行原理:
客户端调用代理,代理的构造方法接受一个Handler,客户端调用代理的各个方法,代理各个方法将调用请求转给handler对象的invoke方法(可以添加新的方法),handler将对应请求分发给对应目标的相应请求。
把需要的功能封装成对象,即把切面你的代码封装成对象,以对象的形式传递,并执行对象就等于执行了切面的代码。
编写可生成代理和插入通告的通用方法:
实现类似spring的可配置的AOP框架:

工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则,返回该类实例对象的getProxy方法返回的对象。
BeanFactory的构造方法接受代表配置文件的输入流对象,配置文件格式如下:
#xxx=java.util,ArrayList
xxx=cn.itcast.ProxyFactoryBean
xxx.target=java.util.ArrayList
xxx.advice=cn.itcast.MyAdvice


Spring两大核心:BeanFactory、AOP