首页 > 技术文章 > 泛型就这么简单

xiaozhongfeixiang 2019-09-15 18:48 原文

为什么需要泛型

public class GenericTest {
public static void main(String[] args) { List list = new ArrayList(); list.add("qqyumidi"); list.add("corn"); list.add(100); for (int i = 0; i < list.size(); i++) { String name = (String) list.get(i); // 1 System.out.println("name:" + name); } } }

 

在如上的编码过程中,我们发现主要存在两个问题:

 1.当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。

 2.因此,// 1 处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常,是因为不能将int类型强制转换为String类型。

  那么有没有什么办法可以使集合能够记住集合内元素各类型,且能够达到只要编译时不出现问题,运行时就不会出现“java.lang.ClassCastException”异常呢?

  答案就是使用泛型。

 

什么是泛型

JDK1.5之后出现了新的技术——泛型(Generic),此技术的最大特点是类中的属性的类型可以由外部决定。 >>(使用者,因为开发者本身并不知道需要什么类型。)

public interface List<E> extends Collection<E>{ //E是元素的意思,只是一个含义,不知道真正代表哪个类型,由外部真正实例化时传进来
  . . . 
}

泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?

顾名思义,就是将类型由原来的变成具体的类型,此时类型也定义成参数形式,然后在使用/调用时传入具体的类型。在写代码的时候不需要关心真正的类型是什么,在使用时才会去关心。

 

@Test public void test1(){
List<string>list = new ArrayList<String>() //<String>可以不写,也可以只写<>,也可以与前面的对应,写上具体的类型。
;list.add("vince");
list.add(10);//报错,因为上面参数化类型具体化了<String>
list.add(new object());//同样报错
for(inti=0;i<list.size();i++){
//如果我们不能确定集合中的元素类型,那么我们需要在处理元素时
//要判断元素的类型,才能做相应的操作
}

 

 

泛型类

定义类:*T:参数化类型,在实际使用时才会指定具体的类到
      泛型只作用于编译期检查,在编译后,会被擦除
*/ public class Node<T>{   private T data;   public Node(){}   public Node(T data){     this.data=data;   }   public T getData(){     return data;   }   public void setData(T data){     this.data=data;   }

 

使用:
@Test
public void testNode(){  Node<String> stringNode = new Node<>("Jack");
  Node<Integer> intNode = new Node<>(10);

   System.out.printin(stringNode.getData());
   System.out.printin(intNode.getData());

}

 

 

  附:Java泛型中的标记符含义: 

  • ? 表示不确定类型,和Object类型不同
  • E 一般表示Element,T 一般表示Type,K一般表示Key,V一般表示Value,不过这些可以混用,没有限制
  • Object 则是包含所有类型

 三种List的生命方法

List<?> list1;
List<E> list2;
List<Object> list3;     

 

Object跟这些标记符代表的java类型有啥区别呢?  

    Object是所有类的根类,任何类的对象都可以设置给该Object引用变量,使用的时候可能需要类型强制转换,

    但是用使用了泛型T、E等这些标识符后,在实际用之前类型就已经确定了,不需要再进行类型强制转换。

jdk中的K,V,T,E等泛型名称不是固定写法,这些名称是可以改的,比如改成zhangsan,lisi都可以

推荐阅读