泛型

一、   定义:

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型 被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

二、   泛型的使用规则:

1)         泛型的基本参数只能是类类型,不能是简单数据类  型。

2)        同一种泛型可以对应不同的版本,不同版本的泛型类是不兼容的。

3)        泛型的参数类型可以有多个。

4)        泛型的参数类型可以用extends或supper以及通配符”?”

5)        泛型可以应用于类,接口,方法。

三、泛型的益处:

1)        避免了类型间的强制转换的风险。

2)        把运行时的异常转移到代码编译时期,降低程序在运行时的发生错误的风险。

四、定义泛型
1)泛型类

class GenericDemo<E>
{
      E e;
 
      public GenericDemo(E e) {
         super();
         this.e = e;
      }
      public E getE() {
         return e;
      }
      public void setE(E e) {
         this.e = e;
      }
}

2)泛型接口

interface IGenericDemo<E>
{
      public void medhod(E e1,E e2);
}

3)泛型方法

class GenericMethod
{
      publicE> voidE
      {
      
      }
}

五、上限泛型

   一种泛型定义为<? extends E>,其中E可以为不同的类型,限定为只能是类型本身或类型的子类型。如:

package cn.javastudy.p7.generic.demo;
import java.util.*;
public class Generic {
   public static void main(String[] args)
   {
      //父类
      Collection<GenericDemo<String>> cl=new ArrayList<GenericDemo<String>>();
      //子类
      Collection<GenericMethod<String>> c2=new ArrayList<GenericMethod<String>>();
      //传父类
      GenericTextDemo<GenericDemo<String>> gtd=new GenericTextDemo<GenericDemo<String>>(cl);
      //传子类
      GenericTextDemo<GenericDemo<String>> gtd1=new GenericTextDemo<GenericDemo<String>>(c2);
   }
}
class GenericDemo<E>
{
   E e;
 
   public GenericDemo(E e) {
      super();
      this.e = e;
   }
 
   public E getE() {
      return e;
   }
 
   public void setE(E e) {
      this.e = e;
   }
   
}
class GenericMethod<E> extends GenericDemo<E>
{
   public GenericMethod(E e) {
      super(e);
      // TODO Auto-generated constructor stub
   }
 
   public <E> void method(E e)
   {
      
   }
}
class GenericTextDemo<E>
{
   //泛型上限的核心代码
   Collection<? extends E> gd=null;
   publicCollection<? extends E> gd) {
      super();
      this.gd = gd;
   }
}

六、泛型下限

   一种泛型定义为<? super E>其中E是任务的类型,此限定为只能是E类型或E类型的父类型。如下:模拟一个TreeSet

package cn.javastudy.p6.generic.demo;
import java.util.*;
public class Generic {
   public static void main(String[] args)
   {
      MyTreeSet<Person> p=new MyTreeSet<Person>(new GenericDemo<Person>(){
 
         @Override
         public int compar(Person e1, Person e2) {
            int temp=e1.getName().compareTo(e2.getName());
            return temp==0?e1.getOld()-e2.getOld():temp;
         }});
      p.add(new Person("a张三",30));
      p.add(new Person("c李四",10));
      p.add(new Person("f王五",80));
      p.add(new Person("d赵六",25));
      p.add(new Person("e刘七",60));
      p.add(new Student("g小明同学",12));
      p.add(new Student("h小张同学",15));
      p.add(new Student("s小杨同学",8));
      p.add(new Student("z小金同学",13));
      Iterator<Person> ip=p.getIterator();
      while(ip.hasNext())
      {
         Person p1=ip.next();
         System.out.println(p1.getName()+" -"+p1.getOld());
      }
   }
}
interface GenericDemo<E>
{
   public int compar(E e1,E e2);
}
class MyTreeSet<E>
{
   LinkedList<E> t=new LinkedList<E>();
   //泛型下限的核心代码
   GenericDemo<? super E> comparator=null;
   public MyTreeSet(GenericDemo<? super E> com)
   {
      this.comparator=com;
   }
   public void add(E e)
   {
      if(t.size()>0)
      {
         for(int i=0;i<t.size();i++)
         {
            int temp=comparator.compar(e, t.get(i));
            if(temp<0)
            {
                t.add(i,e);
                return;
            }
         }
         t.add(e);
      }
      else
      {
         t.add(e);
      }
   }
   @Override
   public String toString() {
      // TODO Auto-generated method stub
      return t.toString();
   }
   public Iterator<E> getIterator()
   {
      return t.iterator();
   }
}
class Person
{
   String name=null;
   int old=0;
   public Person(String name, int old) {
      super();
      this.name = name;
      this.old = old;
   }
   public String getName() {
      return name;
   }
   public int getOld() {
      return old;
   }
}
class Student extends Person
{
 
   public Student(String name, int old) {
      super(name, old);
      // TODO Auto-generated constructor stub
   }
   
}

七、通配符“?”

      泛型还可以用?为通配符,将代表所有类型,转什么类型都可以。如下:

class GenericDemo2
{
   public void Method(List<?> c)
   {
      
   }
}
class GenericDemo2Test
{
   public static void main(String[] args)
   {
      GenericDemo2 gd=new GenericDemo2();
      Vector<Object> vt=new Vector<Object>();
      ArrayList<String> al=new ArrayList<String>();
      gd.Method(vt);
      gd.Method(al);
   }
}

八、使用泛型避免强转的例子。

package cn.javastudy.p7.genericofconvert.demo;
import java.util.*;
public class GenericOfConvert {
   public static void main(String[] args)
   {
      GenericOfConvertDemo god=new GenericOfConvertDemo();
      god.add(new GenericOfConvertDemo1(1));
      god.add(new GenericOfConvertDemo1(2));
      god.add(new GenericOfConvertDemo1(3));
      god.add(new GenericOfConvertDemo1(4));
      god.add(new GenericOfConvertDemo1(5));
      god.add("abc");
      Collection c=god.get();
      Iterator it=c.iterator();
      while(it.hasNext())
      {
         GenericOfConvertDemo1 god1=(GenericOfConvertDemo1)(it.next());
         god1.myPrint();
      }
   }
}
class GenericOfConvertDemo
{
   Collection ct=new ArrayList();
   public void add(Object go1)
   {
      ct.add(go1);
   }
   public Collection get()
   {
      return ct;
   }
}
class GenericOfConvertDemo1
{
   int id;
   public GenericOfConvertDemo1(int id) {
      super();
      this.id = id;
   }
 
   public void myPrint()
   {
      System.out.println("ID:"+this.id);
   }
}

运行结果:

ID:1

ID:2

ID:3

ID:4

ID:5

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to cn.javastudy.p7.genericofconvert.demo.GenericOfConvertDemo1

   at cn.javastudy.p7.genericofconvert.demo.GenericOfConvert.main(GenericOfConvert.java:17)

上面代码中没有加泛型新特性,需要强制转化,当对god.add("abc");成功添加,因为其添加条件为Object,意味着什么类型都可以传进,当在转化时,因为其无法转化为GenericOfConvertDemo1而发生运行时异常。

下在改为使用泛型之后:

package cn.javastudy.p7.genericofconvert.demo;
import java.util.*;
public class GenericOfConvert {
   public static void main(String[] args)
   {
      GenericOfConvertDemo<GenericOfConvertDemo1> god=newGenericOfConvertDemo1>();
      god.add(newGenericOfConvertDemo1(1));
      god.add(newGenericOfConvertDemo1(2));
      god.add(newGenericOfConvertDemo1(3));
      god.add(newGenericOfConvertDemo1(4));
      god.add(newGenericOfConvertDemo1(5));
      //god.add("abc");
      Collection<GenericOfConvertDemo1> c=god.get();
      Iterator<GenericOfConvertDemo1> it=c.iterator();
      while(it.hasNext())
      {
         GenericOfConvertDemo1
         god1.myPrint();
      }
   }
}
class GenericOfConvertDemo<E>
{
   Collection<E> ct=new ArrayList<E>();
   public void add(E go1)
   {
      ct.add(go1);
   }
   public Collection<E> get()
   {
      return ct;
   }
}
classGenericOfConvertDemo1
{
   int id;
   public GenericOfConvertDemo1(int id) {
      super();
      this.id = id;
   }
 
   public void myPrint()
   {
      System.out.println("ID:"+this.id);
   }
}

运行结果:

ID:1

ID:2

ID:3

ID:4

ID:5

因为上面的代码中添加了泛型,所以不需要进行强转。当有//god.add("abc");编译时,就发生了错误。使用了泛型后,不需要强制转换了,把运行时的错误转到了编译时,减少了运行时错误。