黑马程序员------Java基础学习------泛型
来源:互联网 发布:淘宝美工教学视频 编辑:程序博客网 时间:2024/04/29 04:09
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、概述
Java集合有个缺点,当我们把一个对象“丢进”集合里后,集合就会“忘记”这个对象的数据类型,当再次取出该对象时,该对象的编译类型就变成了Object类型。之所以这样,是因为设计集合时不知道我们会用它来存储什么样的类型对象,所以设计成能保存任意对象,但是却带来了两个问题:
- 集合对元素类型没有任何限制,这样可能引发一些问题。例如想创建一个只能保存Person对象的集合,但程序也可以将Student对象“丢”进去,所有可能引发异常。
- 由于把对象“丢进”集合时,集合丢失了对象的状态信息,集合只知道它装的是Object,因此取出集合元素后通常进行强制类型转换,这样不仅增加了编程难道,也可能引发ClassCastException异常。
因此增加了泛型支持后的集合,完全可以记住集合中元素的类型,除此之外,java泛型还增强了枚举类、反射等方面的功能,下面将会讲述定义泛型类、泛型接口、类型通配符、泛型方法等知识。
一、 正文
1、泛型入门
所谓泛型,就是允许在定义类、接口、方法时使用类型形参,这个类型形参将在声明变量、创建对象、调用方法时动态地指定。
首先,先看下面代码:
public class GenericTest { public static void main(String[] args) { ArrayListList list = new ArrayList(); list.add("zhang"); list.add(100); for (int i = 0; i < list.size(); i++) { String name = (String) list.get(i); System.out.println("name:" + name); } }}
上面程序生成了一个ArrayList类型集合,先加了一个字符串类型值,随后加入了一个整形值,这样加完全没有问题,但是取出数据时,确出现了ClassCastException异常。现在利用泛型来重写代码,如下:
public class GenericTest { public static void main(String[] args) { ArrayListList<String> list = new ArrayList<String>(); list.add("zhang"); list.add(100);//提示编译错误 for (int i = 0; i < list.size(); i++) { String name = list.get(i); // 1 System.out.println("name:" + name); } }}
采用泛型写法后,在想加入一个Integer类型的对象时会出现编译错误,通过ArrayListList<String>,直接限定了ArrayListList集合中只能含有String类型的元素,从而无须进行强制类型转换,因为此时,集合能够记住元素的类型信息,编译器已经能够确认它是String类型了。
2泛型类和泛型接口
2.1 定义泛型类
如下,我们看一个最简单的泛型类和方法定义:
public class Test { public static void main(String[] args) { Box<String> name = new Box<String>("corn"); System.out.println("name:" + name.getData()); } }class Box<T> { private T data; public Box() { public Box(T data) { this.data = data; } public T getData() { return data; }}
上面定义了Box<T>类,使用Box<T>类就可以为T类型传入实际参数,这里就通过创建对象为T指定了String类型,那么在Box类里所有T就是String数值类型了。
1.2 定义泛型接口
下面是一个定义接口简单的例子:
interface Info< T>{ // 在接口上定义泛型 public T getVar() ; // 定义抽象方法,抽象方法的返回值就是泛型类型 } class InfoImpl< T> implements Info< T>{ // 定义泛型接口的子类 private T var ; // 定义属性 public InfoImpl(T var){ // 通过构造方法设置属性内容 his.setVar(var) ; } public void setVar(T var){ this.var = var ; } public T getVar(){ return this.var ; } } public class GenericsDemo24{ public static void main(String arsg[]){ Info< String> i = new InfoImpl< String>("小明") ; // 通过子类实例化对象 System.out.println("内容:" + i.getVar()) ; } }
注意:最然程序中只定义了一个接口info<T>,但实际使用时可以产生无数个info接口,主要T传入不同的类型实参,系统就会多一个info子接口。
3、泛型方法
假如需要实现这样一个方法,该方法负责将一个Object数组的所有元素添加到一个Collection集合中。采用如下代码实现该方法:
static void ToCollection(object[] a,Collection<object> c){ for(object o : a){ c.add(o); ]}为解决这个问题,可以使用泛型方法。具体方法格式如下:
修饰符 <T,S> 返回值类型 方法名(形参列表){ //方法体......}
注意:尖括号内可以定义一个或多个类型参数,多个参数的话用逗号隔开,位置放在方法修饰符合方法和方法返回值类型之间。定义的T,S可以在方法内当成普通类型使用,但是只能在该方法里使用。
4、使用类型通配符
为了表示各种泛型List的父类,我们需要使用类型通配符,类型通配符是一个问号(?),将一个问号作为实际参数传给List集合,写作:List<?>,这个问号被称为通配符,它的元素类型可以匹配任何类型。例如:
public void test(List<?> C){
for(int i=0; i<c; i++){
System.out.println(c.get(i));
}
}
4.1 设定类型通配符的上限
一般的时候,有些方法只能处理一部分数据类型,这时候就可以使用上限和下限来确定这个范围,上限的例子如下:
public static void function(Student<? extends Number> s){
System.out.println("姓名是:"+s.getName());
}
程序中的“ ?extends Number” 表示此处的这个未知类型一定是Number子类或者它的本身,因此我们把Number称为这个通配符的上限。
4.2 设定类型通配符的下限
下面是设定下限的例子代码:
public static void function(Student<? super Number> s){
System.out.println("姓名是:"+s.getName());
}
程序中的“? super Number”表示此处的这个未知类型一定是Number的父类或者它的本身,因此我们把这个Number称为这个通配符的下限。
4、使用类型通配符
为了表示各种泛型List的父类,我们需要使用类型通配符,类型通配符是一个问号(?),将一个问号作为实际参数传给List集合,写作:List<?>,这个问号被称为通配符,它的元素类型可以匹配任何类型。例如:
public void test(List<?> C){ for(int i=0; i<c; i++){ System.out.println(c.get(i)); }}
4.1 设定类型通配符的上限
一般的时候,有些方法只能处理一部分数据类型,这时候就可以使用上限和下限来确定这个范围,上限的例子如下:
public static void function(Student<? extends Number> s){ System.out.println("姓名是:"+s.getName()); }
程序中的“ ?extends Number” 表示此处的这个未知类型一定是Number子类或者它的本身,因此我们把Number称为这个通配符的上限。
4.2 设定类型通配符的下限
下面是设定下限的例子代码:
public static void function(Student<? super Number> s){ System.out.println("姓名是:"+s.getName()); }
程序中的“? super Number”表示此处的这个未知类型一定是Number的父类或者它的本身,因此我们把这个Number称为这个通配符的下限。
三、总结
本文主要介绍了JDK1.5提供的泛型支持,比较详细的讲解了如何定义泛型接口、泛型类和泛型方法,以及通配符的用法。
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
- 黑马程序员------Java基础学习------泛型
- 黑马程序员-JAVA基础学习
- 黑马程序员-java学习笔记-java基础
- 黑马程序员-java基础 泛型
- 黑马程序员--java基础--泛型
- 黑马程序员-----Java基础-----泛型
- 黑马程序员-java基础-泛型
- 黑马程序员java学习<基础加强>—泛型
- 黑马程序员—java基础学习--集合类、泛型
- 黑马程序员java基础学习日记
- 黑马程序员第一节java基础学习
- 黑马程序员-java基础学习02-基本知识
- 黑马程序员-java基础-集合学习笔记
- 黑马程序员-java基础-IO学习笔记
- 【黑马程序员】 学习笔记 - Java基础
- 黑马程序员-学习笔记java基础-异常
- 黑马程序员--java基础学习总结
- 黑马程序员--- java基础学习之数组
- Adaptive Cursor Sharing(ACS)的研究
- 对C++中类型兼容规则的认识
- 高清网络摄像机主流芯片方案之安霸、德仪和海思对比
- 标签(2)
- Uiautomator获取控件对象之instance
- 黑马程序员------Java基础学习------泛型
- The method addActionListener(ActionListener) in the type AbstractButton is not applicable for the ar
- Web Service学习笔记
- Travel hnoi省选集训
- ZOJ:3641Information Sharing(并查集)
- 标签(3)
- Callable接口测试
- 常用限制input的方法
- 2015/03/31 百度广告事业部面试基础问答