黑马程序员——泛型-整理笔记

原创 2015年07月09日 15:46:49

                               ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、泛型概念

    泛型(Generic type 或者generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

    限制泛型的可用类型
  由于没有限制class GenericsFoo<T>类型持有者T的范围,实际上这里的限定类型相当于Object,这和“Object泛型”实质是一样的。限制比如我们要限制T为集合接口类型。只需要这么做:
  class GenericsFoo<T extends Collection>,这样类中的泛型T只能是Collection接口的实现类,传入非Collection接口编译会出错。
  注意:<T extends Collection>这里的限定使用关键字 extends,后面可以是类也可以是接口。但这里的extends已经不是继承的含义了,应该理解为T类型是实现Collection接口的类型,或者T是继承了XX类的类型。

    下面我们根据一个例子来理解泛型:

import java.util.ArrayList;
import java.util.List;

 public class Test {
 
     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”异常。

将上面的例子改为采用泛型来定义List

import java.util.ArrayList;
import java.util.List;

public class <span style="font-family:SimSun;">Tes</span>t {

	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("qqyumidi");
		list.add("corn");

		for (int i = 0; i < list.size(); i++) {
			String name = (String) list.get(i); // 1
			System.out.println("name:" + name);
		}
	}
}

   采用泛型写法后,在//1处想加入一个Integer类型的对象时会出现编译错误,通过List<String>,直接限定了list集合中只能含有String类型的元素,从而在//2处无须进行强制类型转换,因为此时,集合能够记住元素的类型信息,编译器已经能够确认它是String类型了。

二、泛型的好处

     ①把运行时的异常转到了编译时期。

     ②避免了程序员强制类型的转换。

    什么时候定义泛型

     当我们定义方法的时候,由于不知道调用者会传入什么样的参数,这时候我们就可以定义泛型,但是当调用者在使用方法的时候,肯定知道自己需要传入什么样类型的参数,所以当调用者调用的时候,就要传入具体的引用数据类型。(不传入泛型的时候,那默认的类型就是Object)

      由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合,再调用其add方法即可。例如:

<span style="font-family:SimSun;">import java.util.ArrayList;

public class tt {

	public static void main(String[] args) throws Exception {

		ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(12);
		list.getClass().getMethod("add", Object.class).invoke(list, "黑马程序员");
		System.out.println(list);

	}</span>
上述代码使用Java反射技术可以往泛型为Integer的ArrayList的对象中放入一个String对象。

三、类型通配符(?)

  泛型的通配符: ?就是通配符

     当我们定义类,方法(参数)不确定的时候,可以用?来表示。例如:

        public void getId(<?> e){}

    由于在方法中,传入的数据类型不确定,所以用到了泛型,但是在调用的时候,调用者肯定知道。如:

        int i = 98;

        getId(i);

        String s ="98";

        getId(s);

泛型就是要限制传递参数类型的,但是又可以接收任意的类型。

   为了表示各种泛型的父类,Java使用"?"来表示泛型通配.即List<?>来表示各种泛型List的父类.带这种通配符List泛型不能设置(set)元素,只能获取(get)元素。因为程序无法确定List中的类型,所以不能添加对象。但获取的对象肯定是Object类型。

例如下面的代码编译时就会出错

             List<?> list = new ArrayList<>();
             list.add(new Object());

泛型的限定

  限定通配符的上边界:

       正确:List<? extends Number> v = new List<Integer>();

       错误:List<? extends Number>v = new List<String>();

  限定通配符的下边界:

       正确:List<? super Integer>v =new List<Number>();

        错误:List<? super Integer>v =new List<Byte>();

   注意:限定通配符总是包括自己。

   泛型上限

      <? extends Collection>这被我们称之为上限,因为只能作用到其最顶层(父类),

     通过这样的定义,可以把其子类当做参数来传递,这主要使用在添加的。 因为在取出的时候方便,不用再进行类型的判断。

   泛型下限

     <? super Comparable> 这就是下限,通常用来进行比较。

    比较的时候既可以使用自己的比较器,也可以使用父类的比较器。


  







                               ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

版权声明:本文为博主原创文章,未经博主允许不得转载。

黑马程序员学习笔记 Java的三大框架

如果做javaweb开发,spring是一定要学的,现在主流还是ssh,就是strurs+hibernate+spring,其中hibernate是持久层,用来持久化数据库操作的,如果不喜欢可以学点别...
  • Mr_April
  • Mr_April
  • 2015年07月03日 17:12
  • 1607

黑马程序员--Struts2复习笔记

--------
  • li951418089
  • li951418089
  • 2015年12月24日 10:26
  • 278

黑马程序员:Hibernate基础知识

android培训、java培训
  • u012159707
  • u012159707
  • 2013年09月26日 15:42
  • 609

黑马程序员——struts2学习笔记一

-----------android培训、java培训、java学习型技术博客、期待与您交流!------------ struts2学习笔记一 一、strust2工作原理...
  • ajin2015
  • ajin2015
  • 2015年08月03日 23:04
  • 866

黑马程序员_Java基础_我的day01学习笔记

01. 常见的DOS命令讲解 A:d: 回车 盘符切换 B:dir(directory):列出当前目录下的文件以及文件夹 C:cd (change directory)改变指定目录(进入指定目录)...
  • qq_21796869
  • qq_21796869
  • 2016年07月05日 10:36
  • 207

黑马程序员--Java基础加强--06.【泛型通配符限定】【个人总结】

泛型通配符限定 总结 ----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------ 本篇日志着重总结extends和super在泛型限...
  • u011406124
  • u011406124
  • 2013年07月30日 09:55
  • 1177

黑马程序员,黑马论坛----分享下收藏~java基础经典知识问题

1、面向对象的特点 抽象: 抽象是或略一个主题中与当前目标的无关的因素,一边充分考虑有关的内容。抽象并不能解决目标中所有的问题,只能选择其中的一部分,忽略其他的部分。抽象包含两个方面:一是过程抽象...
  • asdfasdafasdfhghgf
  • asdfasdafasdfhghgf
  • 2014年08月18日 22:43
  • 293

黑马程序员——JAVA学习整理笔记——常用类库

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 1. StringBuffer 类 1.1 与String比较:       当使用一个字符串...
  • tubao1991
  • tubao1991
  • 2015年03月20日 08:56
  • 116

黑马程序员_泛型总结

---------------------------------------------------android培训、java培训、期待与您交流!---- --------------------...
  • heqinglin8
  • heqinglin8
  • 2014年02月22日 22:21
  • 553

黑马程序员--- 送大家一份毕老师的笔记

文章来源:黑马程序员,黑马论坛。     送大家一份毕老师的笔记,自己一边看,一遍弄的,有很多截图,大家没事看两眼,当复习资料应该不错   http://pan.baidu.com/s/1p...
  • jasjsdajsdjf
  • jasjsdajsdjf
  • 2014年08月16日 20:55
  • 235
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:黑马程序员——泛型-整理笔记
举报原因:
原因补充:

(最多只允许输入30个字)