基础加强-泛型

来源:互联网 发布:淘宝口红哪家是正品 编辑:程序博客网 时间:2024/06/07 02:23

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

                                基础加强-泛型
                                 
一,泛型在定义时可以使用占位符,通配符,来进行类型的指定,但是在实际的使用中一定要传入确定的类型                         
二,泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器带类型说明的集全时会除掉”类型“
信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样,由于编译生成的字节码会去掉泛型的
类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据。例如:用反射得到集合,再调用其add方法即可


三,泛型的术语:
       ArrayList<E>类定义 和 ArrayList<integer>类引用中的涉及如下术语 :
       ·整个称为ArrayList<E>泛型类型
       ·ArrayList<E>中的E称为类型变量或类型参数
       ·整个ArrayList<Integer>称为参数化的类型
       ·ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数
       ·ArrayList<Integer>中的<>念typeof
       ·ArrayList称为原始类型
      
四,参数化类型与原始类型的兼容性:
·参数化类型可以引用一个原始类型的对象。编译只会报告警告:如:Collection<String> collection = new Vector();
·原始类型可以引用一个参数化类型的对象,编译只会报告警告。如:Collection collection = new Vector<String>();

五,参数化类型不考虑类型参数的继承关系:(参数化类型不存在继承关系)
Vector<String> v = new Vector<Object>//不正确 实际可以装入为Object类型的元素,但取出时要String。不写<Object>就可以
Vector<Object> v = new Vector<String>//不正确,Object类型范围太广泛了,不存在继承关系

注:在创建数组实例时,数组的元素不能使用参数化的类型。例如:下面语句有错误:
Vector<Integer> [] vector = new Vector<Integer>[10]; 

六,思考:
Vector v1 = new Vector<String>();正确,参数化类型可以赋值给原始类型
Vector<Object> v = v1;编译没有问题,运行有问题,编译只是检查语法,理解v1为Vector原始类型,将v1赋值给一个参数化类型也是可以的。

七,泛型中的?通配符

1,使用:当使用了通配符来引用一种类型时,不能使用此变量带有参数的方法 如:

public static void sopCollection(Collection<?> collection){ 

collection.add("kdjf")//这是不允许的,可以调用toString()方法,Iterator()方法 size()方法clear方法
}
 
 
总结:使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数无关的方法,不能调用与参数有关的方法
 
八,通配符的扩展

1,限定通配符的上边界:
正确:Vector<? extends Number> x = new Vector<Integer>();?类型是Number类型或Number的子类类型
错误:Vector<? extends Number> x = new Vector<String>();
2,限定通配符的下边界:
正确: Vector<? super Integer> x = new Vector<Number>();?类型是Integer类型或Integer的父类类型
错误: Vector<? super Integer> x = new Vector<Byte>();
提示:限定通配符总是包括自己。


注意思 :
Class<String> clas = Class.forName("java.lang.String");  forName 方法会返回一个Class<?>的类型对象。如果使用实际类型去
是接收不了的,也就相当于Class<String> clas = Class<?> 这是错误的,我们也可以将一个参数化类型赋值给Class<?>.

九,自定义泛型
1,java中的泛型类型(或者泛型)类似于c++中的模板,但是这种相似性仅限于表面,java语言中的泛型基本上完全是在编译器中实现。
用于编译器执行类型检查和类型推断,然后生成普通的非泛型的字节码,这种实现技术称为擦除,(编译器使用泛型类型信息保证类型安全,然后在生成字节码
之前将其清除)这是因为扩展虚拟机指令集来支持泛型被认为是无法接受的,这会为java厂商升级其jvm造成难以逾越的障碍,所以java的泛型采用了可以完全在编译器实现的抢险方法

只有引用类型才能作为泛型方法的实际参数

2,编译器不对new int[2]中的int进行自动的装箱和折箱,因为new int[2]本身已经是对象了,
3,普通方法,构造方法和静态方法中都可以使用泛型。也可以用类型变量表示异常。称为参数化的异常。可以用于方法的throws列表中。但是不能用于catch子句吕
如:
private static <T extends Exception > syaHellow()throws T
{
try{
}
catch(Exception e){//此处必须为具体的类型,不能使用泛型

throw (T)e;
}
4,在泛型中可以同时有多个类型参数,在定义它们的尖括号中用逗号分隔。


}

十,泛型的类型推断
1,当一个方法返回值为泛型时,调用此方法时,返回值类型会和实现接收此返回值的变量的类型一样。如:
定义一个将Object类型的对象转化成任意类型
public stati<T> T autoObject(Object obj){  return (T)obj};
Object ojb = "ak"; String str = autoObject(obj); 此时泛型类型为String

2,具体的规则如下:
·当某个类型就是只在整个参数列表中的所有参数和返回值中的一处被应用了,那么 根据调用方法时该处的实际应用类型确定,这很容易凭着感觉
推断出来,即直接调用方法时传递的参数类型或返回值来决定泛型的类型。如:swap(new String[3],3,4) -> static<E> void swap(E[] a,int i,int j);
·当某个类型变量在整个参数列表听所有参数和返回中的多处被应用了,如果调用方法时这多处的实际应用类型都对应同一种类型来确定。如:
add(3,5)->static <T> T add(T a,T b)
·当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处实际应用类型对应到了不同的类型,且没有使用返回值,这时候
取多个参数中的最大交集类型,如:下面语句实际对应的类型就是Number,则没有了错误:int x = (3,3.5f) -> static <T> T add(T a,T b)
·参数类型的类型推断具有传递性。下面第一种情况推断实际参数类型为Object,编译没有问题,而第二种情况则根据参数化的Vector类实例将类型变量
直接确定为String类型,编译将出现问题:
copy(new Integer[3],new String[5]);->static<T> void copy(T[]a, T[] b);
copu(new Vector<String>(),new String[4]); ->static<T> void copy(T a,T[] b);


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

private T filed1;
public void save(T obj){}
public T getById(int id){}
}
·类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量的,例如,如下两种方法都可以:
GenericDao<String> dao = null;
new GenericDao<String>();

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

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 红米4a电池不耐用怎么办 华为手机买个别人退货的怎么办 京东购物怎么查订单查询不到怎么办 退款了又收到货怎么办快递打电话 快递未收到货能退款商家拒绝怎么办 黑色牛仔裤有一块洗白了怎么办 黑色牛仔裤被洗衣液烧了怎么办 在蘑菇街退鞋子商家非说脏了怎么办 牛皮屑怎么办ke靠成都银康 微信订阅号取消关注之后还在怎么办 腾讯新闻红包领取说帐号异常怎么办 计算机职弥报名没选模块怎么办 有人用我手机注册有赞了怎么办 一件代发别人的货被投诉了怎么办 淘宝极速退款后商家拒收快递怎么办 运费险退到天猫垫付账户了怎么办 淘宝卖家食品有问题该怎么办 美团外卖不要辣椒给放了怎么办 旺旺卖家拒收我的消息怎么办 淘宝清空购物车大奖到上限了怎么办 游戏无响应除了退出还能怎么办 淘宝给差评了卖家一直打电话怎么办 电脑说带宽问题无法观看视频怎么办 手机淘宝上的购买信息删除了怎么办 为什么支付宝有钱淘宝付不了怎么办 苹果平板电脑上的淘宝点不开怎么办 淘宝付了两次款只有一个订单怎么办 淘宝付款显示支付宝账号异常怎么办 手机老卡换新卡淘宝付不了款怎么办 淘宝买东西退款卖家拒绝退款怎么办 淘宝店铺收藏图片怎么点不了怎么办 手机淘宝显示用户被限制登录怎么办 淘宝设置登录密码原密码忘了怎么办 斑马智行淘宝号换没法登录了怎么办 淘宝卖家手机版显示宝贝不全怎么办 在电脑上登的淘宝账号退不了怎么办 淘宝买家退款不退货写假货怎么办 淘宝卖家已发布商品没货了怎么办 京东换货附近没有京东自提点怎么办 一直显示手机淘宝已停止运行怎么办 唯品会买了不可以退货的衣服怎么办