知识大全 J2SE5.0新特性示例---泛型
Posted 类型
篇首语:守望相助,一缕阳光也将照亮心扉;同心协力,一点火光也能温暖灵魂。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 J2SE5.0新特性示例---泛型相关的知识,希望对你有一定的参考价值。
J2SE5.0新特性示例---泛型 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
简介
泛型其实并不是一种新的语言元素 C++中早就就有 但是在C++之后的java却没有吸收这个特性 现在Java也有了泛型的特性 大概也和 Net的竞争有关系吧
首先看泛型的一个应用
在过去 我们可能经常要写一些类似这样的代码
List stringList=new LinkedList();stringList add( firstString );stringList add( secondString );String str=(String)erator() next();
实际上第三行对String的类型转换意义并不大 因为通常我们如果在操作一个List 都是知道这个List里面放的是什么类型对象的 但是我们如果不这样写又通不过语法检查
利用java的泛型机制 我们可以这么写
List<String> stringList=new LinkedList<String>();stringList add( firstString );stringList add( secondString );String str=erator() next();
这样做的好处是在定义容器的时候就指明了容器中的类型 一方面我们不再需要取一个元素时候做强制类型转换 另外一方面如果在这个容器中放入的对象类型不符合要求 那么会在编译时候产生一个错误 而不是在运行时候才抛出一个异常
另外这样也提高了程序的可读性
泛型类型的定义
下面是一个简单的使用泛型类的定义
public class MyGenericClass<T> private T value;
public T getValue() return value;
public void setValue(T value) this value = value;
值得注意的一点是 静态变量不能够使用泛型定义 也就是说类似下面的语句是非法的
public class MyGenericClass<T> public static T value;//错误的定义
此外 泛型的定义不会被继承 举个例子来说 如果A是B的子类 而C是一个声明了泛型定义的类型的话 C<A>不是C<B>的子类 为了更好的说明 可以看下面的代码 这段代码是错误的
List<String> strList =new ArrayList<String>();List<Object> objList=strList; //错误的赋值
不过这样一段代码是正确的
List<Object> strList =new ArrayList<Object>();strList add( a string );
统配类型
假设我们需要这样一个函数 使用它可以把一个集合中所有的元素打印出来 在以前我们可能这样定义
void printCollection(Collection c) Iterator i = erator(); for (k = ; k < c size(); k++) System out println(i next());
使用新的泛型特性我们可以这样写
void printCollection(Collection<Object> c) for (Object e : c) System out println(e);
但是这样有一个问题 假如我们现在有个对象类型是Collection<String> 那么我们不能够将它作为参数传给printCollection 因为Collection<String>并不是Collection<Object>的子类
为了解决这个问题 我们可以使用统配类型? 也就是定义成下面这个样子
void printCollection(Collection<?> c) for (Object e : c) System out println(e);
可以说Collection<?>是所有Collection的父类
再来看一段下面的代码
private void clearAllMaps(Collection<Map> c) for(Map m:c) m clear();
毫无疑问 它也存在上面我们所说的问题 也就是对HashMap之类Map的子类无法进行操作 但是如果我们将参数改成Collection<?>又不大合理 因为我们只希望对父类为Map的子类进行操作 那么我们可以这样改写
private void clearAllMaps(Collection<? extends Map> c) for(Map m:c) m clear();
类似于? extends Map之类的统配符称为限定统配类型
假设一个对象h类型为Collection<HashMap> 那么我们将h作为参数传给clearAllMaps 如下面一段代码所示
List<HashMap<String String>> h=new ArrayList<HashMap<String String>>();HashMap<String String> m=new HashMap<String String>();m put( key value );h add(m);clearAllMaps(h);
对于在类似于上面所说 使用了? extend XXX的方法 值得注意的一点是不能够在方法体内用XXX的子类对象作为代替 如下面一段代码是错误的
public void addRectangle(List<? extends Shape> shapes) shapes add( new Rectangle()); // 错误用法!
这里我们假设Rectangle是Shape的一个子类
不允许这样写的原因比较简单 因为调用该方法时候参数类型可能是Shape的另外一个子类 假如说Shape除了Rectangle这个子类以外还有另外一个子类Circle 那么我们可以把一个List<Circle>类型的对象作为参数传给这个方法(注意这样是合法的) 而在方法体内却把一个Rectangle对象放到了shapes里面 这显然是不合理的
除了extends 在泛型参数类型中还可以使用super关键字 参照下面一段程序
private void addString(Collection <? super String> c) c add( a String );泛型函数
我们在前面提到了统配类型 现在让我们来设想一个函数 它实现这样的功能 将一个数组中的元素添加到一个Collection中 为了保证程序的通用性 我们可能会写出另外一段错误的代码
private void fromArrayToCollection(Object[] a Collection<?> c) for (Object o : a) c add(o); // 错误的代码
那么这个函数应该怎么写呢?我们可以通过对函数添加泛型参数的方法实现 如下面所示
private <T> void exfromArrayToCollection(T[] a Collection<T> c) for (T o : a) c add(o); //这样是正确的
那么 在什么时候我们应该使用统配类型 什么时候我们应该使用泛型函数呢?答案是取决于函数参数之间 函数参数和返回值之间的类型依赖性
如果一个函数的参数类型与函数返回的参数没有必然关联 同时对于该函数其他的参数的类型也没有依赖关系 那么我们就应该使用统配符 否则就应该使用泛型函数
为了更清楚地说明这一点 我们可以看一下java util包中Collections类型几个方法的定义
class Collections static void swap(List<?> list int i int j) static <T> void copy (List<? super T> dest List<? extends T> src)
其中swap函数实际上也可以这样定义
static <T>void swap(List<T> list int i int j)
但是注意到这里泛型类型参数T只在参数中用到了一次 也就是说它和函数其他部分没有依赖性 这可以看作是我们应该使用?的一个标志
cha138/Article/program/Java/Javascript/201311/25360相关参考
知识大全 在Eclipse 3.1体验J2SE 5.0新特性六
在Eclipse3.1体验J2SE5.0新特性六 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 在Eclipse 3.1体验J2SE 5.0新特性四(图)
在Eclipse3.1体验J2SE5.0新特性四(图) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 在Eclipse 3.1体验J2SE 5.0新特性二(图)
在Eclipse3.1体验J2SE5.0新特性二(图) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 在Eclipse 3.1体验J2SE 5.0新特性七(图)
在Eclipse3.1体验J2SE5.0新特性七(图) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
知识大全 在Eclipse 3.1体验J2SE 5.0新特性八(图)
在Eclipse3.1体验J2SE5.0新特性八(图) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
J2SE(TM)5.0语言特性 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! [C风格格式化输出
JDK5.0中的泛型类型学习 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! JDK中增加的泛型类
MySQL5.0新特性教程存储过程:第二讲 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Why
MySQL5.0新特性教程存储过程:第一讲 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Int
MySQL5.0数据库新特性的存储过程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 当你提交一