泛型:编译器编译带类型说明的集合就是去掉类型信息。
ArrayList<E>
整个称为ArrayList的泛型类型
E称为类型变量或类型参数
ArrayList<Integer>称为参数化的类型
Integer称为类型参数的实例或实际类型参数,只有对象的引用类型才能作为泛型的实际类型参数。
读法:<>念type of
ArrayList 原始类型
参数化类型与原始类型的兼容性
Collection<String> = new Vector();
Collection c = new Vector<String>();
上面两种都是可以的,虽然编译器会警告
参数化类型不考虑类型参数的继承关系:
Vector<String> v = new Vector<Object>();//错误
Vector<Object> v = new Vector<String>();//也错误
在创建数组实例时,数组的元素不能使用参数化的类型:
Vector<Integer> vectorList[] = new Vector<Integer>[10];//错误
Vector v1 = new Vector<String>();//可以
Vector<Object> = v1; //这个编译也能通过,编译器是严格按照一行一行的语法来判断的。
泛型中的 ?通配符:
通配符上边界:? extends Number
通配符下边界:? super Integer
并且可以用&限定多个边界。
java语言中的泛型基本上是在编译器中实现的,用于编译器执行类型检查和类型判断,
在生成字节码后会删除,这种称之为擦除。
private static <T> void swap(T[] a,int i,int j){
T temp = a[i];
a[i] = a[j];
a[j] = temp;
}
只有引用类型才能作为泛型方法的实际参数,swap(new int[3],3,5)会报错。
异常采用泛型:
把Object类对象转成其他类对象:
private static <T> T autoConvert(Object obj)
{
return (T)obj;
}
泛型方法的类型参数的类型推断:根据调用泛型方法时实际传递的参数类型或返回值的类型来推断:
1.参数列表中只有一处被调用,直接根据调用方法时传递的参数类型或返回值来决定
2.多处对应同一种类型,可以凭感觉推断出来
3.多处对应不同类型,且没有返回值,这时去多个参数的最大交集类型
4.多处对应不同类型,且有返回值类型,优先考虑返回值类型
dao:data access object-->crud
定义泛型类型:如果类的实例对象中的多处用到泛型,可以把泛型定义在类上。
当一个变量被声明是泛型时,只能被实例变量和方法调用(还有内嵌类型),而不能被静态
变量和 静态方法调用。因为静态成员是被所有参数化的类所共享的,所以静态可以自己单独
定义泛型变量。
通过反射获得泛型的实际类型参数: ******
ArrayList<E>
整个称为ArrayList的泛型类型
E称为类型变量或类型参数
ArrayList<Integer>称为参数化的类型
Integer称为类型参数的实例或实际类型参数,只有对象的引用类型才能作为泛型的实际类型参数。
读法:<>念type of
ArrayList 原始类型
参数化类型与原始类型的兼容性
Collection<String> = new Vector();
Collection c = new Vector<String>();
上面两种都是可以的,虽然编译器会警告
参数化类型不考虑类型参数的继承关系:
Vector<String> v = new Vector<Object>();//错误
Vector<Object> v = new Vector<String>();//也错误
在创建数组实例时,数组的元素不能使用参数化的类型:
Vector<Integer> vectorList[] = new Vector<Integer>[10];//错误
Vector v1 = new Vector<String>();//可以
Vector<Object> = v1; //这个编译也能通过,编译器是严格按照一行一行的语法来判断的。
泛型中的 ?通配符:
public static void printCollection(Collection<?> cols)
{
for(Object obj:cols)
{
System.out.println(obj);
}
//cols.add("String");//错误,因为不知道到未来匹配的一定就是String
cols.size();//ok,此方法与类型参数无关
cols = new HashSet<Date>();
}
通配符上边界:? extends Number
通配符下边界:? super Integer
并且可以用&限定多个边界。
java语言中的泛型基本上是在编译器中实现的,用于编译器执行类型检查和类型判断,
在生成字节码后会删除,这种称之为擦除。
private static <T> void swap(T[] a,int i,int j){
T temp = a[i];
a[i] = a[j];
a[j] = temp;
}
只有引用类型才能作为泛型方法的实际参数,swap(new int[3],3,5)会报错。
异常采用泛型:
private static <T extends Exception> sayHello()throws T
{
try
{
}catch (Exception e){
throw (T)e;
}
}
把Object类对象转成其他类对象:
private static <T> T autoConvert(Object obj)
{
return (T)obj;
}
泛型方法的类型参数的类型推断:根据调用泛型方法时实际传递的参数类型或返回值的类型来推断:
1.参数列表中只有一处被调用,直接根据调用方法时传递的参数类型或返回值来决定
2.多处对应同一种类型,可以凭感觉推断出来
3.多处对应不同类型,且没有返回值,这时去多个参数的最大交集类型
4.多处对应不同类型,且有返回值类型,优先考虑返回值类型
dao:data access object-->crud
定义泛型类型:如果类的实例对象中的多处用到泛型,可以把泛型定义在类上。
当一个变量被声明是泛型时,只能被实例变量和方法调用(还有内嵌类型),而不能被静态
变量和 静态方法调用。因为静态成员是被所有参数化的类所共享的,所以静态可以自己单独
定义泛型变量。
通过反射获得泛型的实际类型参数: ******
Vector<Date> v = new Vector<Date>();//通过v是无法获得其泛型的类型
public static void applyVector(Vector<Date> v)//不过可以通过应用该变量的方法来返回该方法的参数的泛型类型。
{}
public static void main(String[] args)
{
Method applyMethod = GenericTest.class.getMethod("applyVector",Vector.class);
Type[] types = applyMethod.getGenericParameterTypes();
ParameterizedType pType = (ParameterizedType)types[0];
System.out.println(pType.getRawType());
System.out.println(pType.getActualTypeArguments()[0]);//返回此类的实际参数类型的Type对象的数组,因为参数类型可能有多个
}