黑马程序员------------------泛型

来源:互联网 发布:变色龙运行mac黑屏 编辑:程序博客网 时间:2024/06/05 19:26
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

泛型:jdk1.5以后出现的新特性。用于解决安全问题,是一个类型安全机制。



好处:
1.将运行时期出现的ClassCastException问题转移到了编译时期
方便程序员解决问题。
2.避免了强制转换麻烦。


泛型格式:通过<>来定义要操作的引用数据类型。


在使用java提供的对象时,什么时候写泛型呢
通常在集合框架中很常见。其实<>就是用来接受类型的。
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
当类中要操作的引用数据类型不确定的时候,而早期通过定义Objecct来完成扩展。

class Tool<T>{private T t;public void setT(T t){this.t = t;}public T getT(){return t;}}


泛型类定义的泛型,在整个类中有效,如果被方法使用,泛型类的对象明确要操作的具体类型后,所有
要操作的类型就已经固定了。
为了让不同方法可以操作不同类型,而且类型还不确定。可以将泛型定义在方法上。
注意:静态方法不可以访问类上定义的泛型。如果需要定义泛型,可以将泛型定义在方法上。
泛型也可以定义在接口上。

class Demo<T>{public void show(T t)//方法上的泛型和类的泛型相同{}public <Q> void print(Q q)//也可以在泛型类中存在泛型方法{}public static <W> void method(W w)//静态方法定义泛型{}}



 

泛型限定:
 通配符,也可以理解为占位符。
上限:? extends T: 可以接受T类型或者其子类 :addAll(Collection<? extends E> c)
下限:? super T:可以接受T类型或者其父类  :TreeSet(Comparator<? super E>)
java中的类只支持单继承。

 

 泛型:编译器编译带类型说明的集合就是去掉类型信息。
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");//错误,因为不知道到未来匹配的一定就是Stringcols.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对象的数组,因为参数类型可能有多个}


 

 

---------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流!---------------详细请查看:http://edu.csdn.net

 

 

 

0 0