Java泛型初衷

一、泛型初衷

      Java集合不会知道我们需要用它来保存什么类型的对象,所以他们把集合设计成能保存任何类型的对象,这要就具有很好的通用性。但这样做也带来两个问题:

  –集合对元素类型没有任何限制,这样可能引发一些问题:例如想创建一个只能保存Dog对象的集合,但程序也可以轻易地将Cat对象“丢”进去,所以可能引发异常。
  –由于把对象“丢进”集合时,集合丢失了对象的状态信息,集合只知道它盛装的是Object,因此取出集合元素后通常还需要进行强制类型转换。这种强制类型转换既会增加编程的复杂度、也可能引发ClassCastException。

二、什么是泛型

  所谓泛型:就是允许在定义类、接口指定类型形参,这个类型形参在将在声明变量、创建对象时确定(即传入实际的类型参数,也可称为类型实参)。

  JDK1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持,从而可以在声明集合变量、创建集合对象时传入类型实参。

      值得注意的是并不存在泛型类

  虽然可以把ArrayList<String>类当成ArrayList的子类,事实上ArrayList<String>类也确实是一种特殊的ArrayList类,这个ArrayList<String>对象只能添加String对象作为集合元素。但实际上,系统并没有为ArrayList<String>生成新的class文件,而且也不会把ArrayList<String>当成新类来处理。
  实际上,泛型对其所有可能的类型参数,都具有同样的行为,从而可以把相同的类被当成许多不同的类来处理。与此完全一致的是,类的静态变量和方法也在所有的实例间共享,所以在静态方法、静态初始化、或者静态变量的声明和初始化中不允许使用类型形参。
  系统中并不会真正生成泛型类,所以instanceof运算符后不能使用泛型类。

三、深入泛型

1.定义泛型接口、类

  定义Apple类时使用了泛型声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 定义Apple类时使用了泛型声明
public  class  Apple<T>
{
     // 使用T类型形参定义实例变量
     private  T info;
     public  Apple(){}
     // 下面方法中使用T类型形参来定义构造器
     public  Apple(T info)
     {
         this .info = info;
     }
     public  void  setInfo(T info)
     {
         this .info = info;
     }
     public  T getInfo()
     {
         return  this .info;
     }
     public  static  void  main(String[] args)
     {
         // 由于传给T形参的是String,所以构造器参数只能是String
         Apple<String> a1 =  new  Apple<>( "苹果" );
         System.out.println(a1.getInfo());
         // 由于传给T形参的是Double,所以构造器参数只能是Double或double
         Apple<Double> a2 =  new  Apple<>( 5.67 );
         System.out.println(a2.getInfo());
     }
}
 四、类型通配符
     使用List<?>这种形式是,即表明这个List集合可以是任何泛型List的父类。但还有一种特殊的情形,我们不想这个List<?>是任何泛型List的父类,只想表示它是某一类泛型List的父类。  
  我们需要一种泛型表示方法,它可以表示所有Shape泛型List的父类,为了满足这种需求,Java泛型提供了被限制的泛型通配符。被限制的泛型通配符的如下表示:List<? extends Shape> ,List<? super Shape> 


五、擦除与转换
  在严格的泛型代码里,带泛型声明的类总应该带着类型参数。但为了与老的Java代码保持一致,也允许在使用带泛型声明的类时不指定类型参数。如果没有为这个泛型类指定类型参数,则该类型参数被称作一个raw type(原始类型),默认是该声明该参数时指定的第一个上限类型。
  当把一个具有泛型信息的对象赋给另一个没有泛型信息的变量时,则所有在尖括号之间的类型信息都被扔掉了。 比如说一个List<String>类型被转换为List,则该List对集合元素的类型检查变成了成类型变量的上限(即Object),这种情况被为擦除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值