1,如果类的实例对象中的多处都要用到同一个泛型参数,即这些地方引用的泛型类型要保持同一个实际类型时,这时候就要采用泛型类型的方式进行定义,也就是类级别的泛型,语法格式如下:
public class GenericDao<T> {
private T field1;
public void save(T obj){}
public T getById(int id){}
}
2,类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量的,例如,如下两种方式都可以:
GenericDao<String> dao = null;
new genericDao<String>();
注意:
在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。
当一个变量被声明为泛型时,只能被实例变量、方法和内部类调用,而不能被静态变量和静态方法调用。因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。
3,通过反射获得泛型的参数化类型:
Class GenericalReflection {
private Vector<Date> dates = new Vector<Date>();
public void setDates(Vector<Date> dates) {
this.dates = dates;
}
public static void main(String[] args) {
Method methodApply = GenericalReflection.class.getDeclaredMethod("applyGeneric", Vector.class);
ParameterizedType pType = (ParameterizedType)
(methodApply .getGenericParameterTypes())[0];
System.out.println("setDates("
+ ((Class) pType.getRawType()).getName() + "<"
+ ((Class) (pType.getActualTypeArguments()[0])).getName()
+ ">)" );
}
}
4,Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader
类加载器也是Java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是不是java类,这正是BootStrap。
Java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象时,需要为其指定一个父级类装载器对象或者默认采用系统类装载器为其父级类加载。
5,类加载器的委托机制:当Java虚拟机要加载一个类时,首先当前线程的类加载器去加载线程中的第一个类。如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。 还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。每个类加载器加载类时,又先委托给其上级类加载器。
当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有getChild方法。
6,每个ClassLoader本身只能分别加载特定位置和目录中的类,但它们可以委托其他的类装载器去加载类,这就是类加载器的委托模式。类装载器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,然后才一级级回退到子孙类装载器去进行真正的加载。当回退到最初的类装载器时,如果它自己也不能完成类的装载,那就应报告ClassNotFoundException异常。