java 泛型(一)
来源:互联网 发布:知乎变成蛤乎了 编辑:程序博客网 时间:2024/03/29 08:32
- 什么是泛型?什么是原生类型(raw type)?
声明中具有一个或多个类型参数(type parameter)的类或者接口就是泛型类或者泛型接口。
泛型类和泛型接口同称为泛型。
每个泛型都有一个原生类型(raw type),既不带任何类型参数的泛型,原生类型与java没有泛型之前的接口是一样的。
List<E>和List(raw type)
- 为什么使用泛型?
- 代码复用
- 编译时的类型检查:编译器会对使用泛型的代码进行类型检查,如果违反了类型,安全编译器会抛出警告,编译时发现错误要比运行时发现错误好的多。
- 消除转型
没有使用泛型:
List list = new ArrayList();String s = (String) list.get(0);list.add("hello");
使用泛型:
List<String> list = new ArrayList<String>();list.add("hello");String s = list.get(0); // no cast
我们来对比一下java 1.5之前没有泛型和又了泛型之后的差别:
//java 1.5之前//class Stamp{}//class Coin{}private final Collection stamps=...stamps.add(new Coin());// 通过编译,并且不会出现错误提示,只会警告你,但警告有可能被忽略//直到从stamps获取coin时,才会收到错误提示for(Iterator i=stamps.iterator();i.hasNext()){Stamp s=(Stamp)i.next(); //抛出ClassCastException}
//有了泛型之后private final Collection<Stamp> stamp=...stamp.add(new Coin()); // 报错:add(Stamp) can not be applied to Coin;
那么问题来了,如果不提供参数类型,使用集合类和其他泛型类也是合法的,但是不应该这么做,原因:
如果使用原生类型,就失去了泛型在安全性和表述下方面的优势。
既然如此,为什么还有原生类型存在呢?这是为了提供兼容性,其实就是保持没有使用泛型(java 1.5之前)的java代码的合法性。
这里还有一个特殊的情况需要强调一下:List<Object>
不严格的说,原生类型List逃过了编译检查,而List<Object>告诉编译器,它能够持有任何对象。
List l1 = new List<String>(); //合法List<Object> l2 = new List<String> // 不合法 Incompatible types
因此使用List会丢失安全性,但是List<Object>则不会
举例:
原生类型可以通过编译,但是收到了一条警告。
public static void main(String args []){ List<String> l=new ArrayList<String>(); safeAdd(l,3); } public static void safeAdd(List list, Object obj){ list.add(obj); //Unchecked call to 'add(E)' as a member of raw type }
使用List<Object>,编译器提示错误。
public static void main(String args []){ List<String> l=new ArrayList<String>(); safeAdd(l,3); // 报错 } public static void safeAdd(List<Object> list, Object obj){ list.add(obj); }
- 无限制的通配符类型。如果我不想使用泛型,但是又想确保类型安全该怎么办?
这是由上面的最后例子引出的一个问题。有时候可能我们不在乎或者不确定集合中的元素类型,该怎么办?
- 我们可以使用原生类型,但是有什么坏处?如果不知道 ,再看看上面的例子。
//use of raw type for unknown element type -- don't do this static int numElementInCommon(Set s1,Set s2){ int result=0; for(Object o1:s1){ if(s2.contains(o1)) result++; } return result; }
- java 1.5发型版开始提供了更安全的替代方法,即无限制的通配符类型(unbounded wildcard type)
某个类型的集合,只是我不关心或者不确定时什么集合,Set<?> 这是普通的参数化Set类型,可以持有任何集合。
static int numElementInCommon(Set<?> s1,Set<?> s2){ int result=0; for(Object o1:s1){ if(s2.contains(o1)) result++; } //s1.add(null); //s1.add(1); //报错 return result; }
那么无限制的通配符安全在哪呢?它只允许加入null,其他类型的都不可以。
这虽然不是很令人满意,但是编译器已经尽到它的职责,防止你破坏集合的类型约束。如果无法接受这些限制,可以使用泛型方法后者有限制的通配符(bounded wildcard type)
- 下面两种例外可以不使用泛型:
instanceof: 与泛型信息在运行时擦除有关class literal:List.class而不是List<?>.class
1 0
- Java泛型(一)
- Java 泛型(一)
- Java泛型(一)
- java泛型(一)
- java 泛型(一)
- java泛型(一)
- Java泛型(一)
- java泛型(一)
- 解析java泛型(一)
- 理解Java 泛型(一)
- Java泛型---学习(一)
- Java读书笔记-泛型(一)
- java学习笔记(一)泛型
- 【effective java读书笔记】泛型(一)
- Java笔记(一)——泛型
- Java泛型 (一)
- JAVA泛型 一
- Java泛型(一)
- WEBP
- Java Servlet
- forward和redirect的区别
- Ubuntu下Elasticsearch安装问题
- Fresco 使用笔记(一):加载gif图片并播放
- java 泛型(一)
- ntp
- linux访问windows共享文件的方法
- Unity3D实现摄像机视野的拉远拉近和跟随主角旋转效果
- 一个简单的Java开发WebService实例
- enable_share_from_this 模板类使用和完全解析
- ->在C
- Node.js + MongoDB + AngularJS - 6 访问文件系统-1
- IOS中UIImageView使用网络图片