泛型
泛型:在JDK1.4之前,容器什么类型的对象都可以存储,但是在取出时
      需要用到对象的特有内容时,需要向下转型,
      但是对象的类型不一致,导致了向下转型发生了ClassCastException
      为了避免这个问题,只能主观上控制,往集合中存储的对象类型保持一致
JDK1.5以后,在定义集合时,就直接明确了集合中存储元素的具体类型,
这样,编译器在编译时,就可以对集合中存储的对象类型进行检查,
一旦发现类型不匹配,就编译失败,这个技术就是泛型。
  |
  |好处:1.将运行时期的问题转移到了编译时期。
  |      2.避免了向下转型的麻烦。
  |*总结:泛型就是应用在编译时期的一项安全机制。
  泛型的擦除:编译器通过泛型对元素类型进行检查,只要检查通过,
              就会生成class文件,但在class文件中,泛型的标识被去掉了
泛型类
背景前提:
        当创建一个工具类的时候,想要对对象进行操作,但是对象类型不明确,
        为了能使该类可以操作所有对象,可以使用Object类型来完成。
        But弊端:
        当出现转型的时候,如果类型输入的不一样,该错误无法在编译时期
        被发现,所以就会出现类型转换异常,为了解决这种问题,所以可以
        对外提供参数,由使用者通过传递参数的形式完成类型的确定。
例:1
2
3
4
5
6
7
8
9
10
11
12class Tool<lei>
{
   private lei obj;
   public lei getObj()   
   {
     return obj;
   }
   public void setObj(lei obj)
   {
     this.obj = obj;
   }
}
使用方式如下:1
2
3
4
5
6main{
  Tool<student> T = new Tool<student>();
  T.setObj(new Student());
  Student stu = T.getObj();
  Syso(stu);
}
优点:在使用时就明确了要输入什么类型,这样子如果之后输入错误就会被编译器报错,
      并且这样使用不需要向下转型!
注意:静态方法无法访问类上定义的泛型的。
       如果静态方法需要定义泛型,泛型只能定义在方法上。
泛型方法
背景前提:
       class Demo
       {
             public void show(W w)
             {
                 System.out.println(“show:”+w);
              }
              public void print(W w)
              {
                 System.out.println(“print:”+w);
              }
        }
当我在使用该类时
    Demo<String> d = new Demo<String>();
    d.show("a");
    d.print(6);
以上就会被报错,因为我已经声明了W类是String,
如果我想要打印出6,我就必须新建一个W是整型类的Demo类,
为了解决这个问题,我们可以使用泛型方法。
    public <Q> void print(Q w)
    {
        System.out.println("print:"+w);
     } 
在方法类型之前写一个泛型,这样子就可以解决以上问题。
泛型接口
1  | interface Inter<T>//  | 
泛型的限定
 <? extends E> -上限:接收E类型或者E的子类型
 <? super E>   -下限:接收E类型或者E的父类型
上限:一般往容器中存储元素时,如果集合定义了E类型,并且需要可以接收E类型的子类型
      这时就需要将泛型从
下限:一般从容器中取出元素时,可以用E类型接收,也可以用E的父类型接收。
所以可以用<E>,也可以用<? super E>
通配符 ?
//在不明确具体类型的情况下,可以使用通配符表示
例如:我想要实现一个输出函数,专门打印出集合
    List
    Set
    printcoll(list);
    printcoll(set);
    private static void printcoll(Collection<?> coll)
    {
       for(Iterator<?> it = coll.iterator(); it,hasNext();)
       {
           Object obj = it.next();
           System.out.println(obj);
          //迭代器输出功能
       }
    }