泛型详解
来源:互联网 发布:局域网即时通信软件 编辑:程序博客网 时间:2024/04/27 14:55
通过引入泛型,我们可以获得的优势: 泛型是在JDK 1.5之后引入的
编译时类型的安全
和运行时更小的抛出ClassCastExceptions的可能。
泛型是变量类型的参数化
泛型是解决什么问题的,
我们都知道一个集合可以添加不同类型的对象,但是在获取对象的时候,必须要知道所有对象的类型才可以取出来,存进去没什么代价,但是取出来的时候代价太大,泛型就是解决集合中存在不同类型对象时的存取问题。
public class GenericityTest { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(1); list.add("sss"); list.add(false); for(int i=0;i < list.size();i++){ String s1=(String)list.get(i); // 会抛出类型异常 System.out.println(s1); } }}
能用泛型的时候一定要使用泛型,尤其是在使用集合的时候
在定义泛型类别的时候,预设可以使用任何的类型来实例化泛型中的类型,但是如果想要限制泛型类别的使用类型,只能用某个特定类型或者其子类型才能实例化该类型的时候,可以在定义类型的时候,使用extends关键字指定这个类型必须是继承自某个类或者实现了某个接口
下面的例子详细的讲解了泛型。
需要注意的是 在下面的例子中,虽然List是接口,但是在泛型中也必须使用extends关键字表明,这是语法要求
public class GenericityTest2<T extends List>{ public static void main(String[] args) { // ArrayList也是使用了泛型实现的,要求以后在使用集合的时候一定要使用泛型 ArrayList<String> list = new ArrayList<String>(); // 使用了泛型之后必须使用它所规定的类型,否则程序编译不通过 // list.add(100); 错误的 list.add("aaa"); list.add("bb"); for(Iterator<String> iter = list.iterator(); iter.hasNext();){ // String s1 = (String)iter.next(); 未使用泛型时,需要对iter.next() 进行强制类型转换,因为返回的是一个Object对象 // 使用了泛型,就不必再进行强制类型转换,因为系统已经知道对象的类型是String类型 String s1 = iter.next(); System.out.println(s1); } HashMap<String,String> hash = new HashMap<String, String>(); hash.put("aa","aaa"); hash.put("bb","bbb"); // GenericityTest2<T> 如果这样书写,那么他可以传进任意类型的数组, // 但是 GenericityTest2<T extends List> 就对传进来的类型做了要求,传进来的对象类型必须是实现了 List接口的 GenericityTest2<ArrayList<String>> a = new GenericityTest2<ArrayList<String>>(); // 因此当传进来一个HashMap后程序报错,因为HashMap没有实现List 接口 // List 是接口,但是在泛型中依旧使用extends 来声明,记住 // GenericityTest2< HashMap<String,String>> b = new GenericityTest2< HashMap<String,String>>(); } private T[] t; public T[] getT() { return t; } public void setT(T[] t) { this.t = t; } }
当泛型没有指定泛型继承的类型或接口时,默认是 extends Object
GenericTest3
import java.util.ArrayList;import java.util.LinkedList;import java.util.List;public class GenericTest3<T> { private T foo; public T getFoo() { return foo; } public void setFoo(T foo) { this.foo = foo; } public static void main(String[] args) { // 可以实现与 GenericTest3<T extends List>一样的功能,必须是实现了List的接口的 GenericTest3<? extends List> ge =null; ge=new GenericTest3<ArrayList>(); ge=new GenericTest3<LinkedList>(); GenericTest3<String> ge2 =null; ge2.setFoo("String"); GenericTest3<? extends Object> ge3; // 上面一句的等价 ==GenericTest3<? > ge3 一般都是使用这个,默认是继承Object的 // 设置为空,或者将一个特定类型的提取到ge3是没有什么问题的 ge3=null; ge3=ge2; // 但是利用它来进行对子类类型的对象赋值时,程序会报错// ge3.setFoo("String"); 这样是编译错误的,原因是ge3只知道它是一个实现了Object的对象, // 即是Object的一个子类,但不确定是什么类型,因此编译器不让加入信息,如果你能加入信息的话 // 系统就会认为你已经知道了它的类型,当你调用ge3.getFoo,返回的是一个Object对象,你就必须得进行 //强制类型转换才能使用,而泛型就是设计出来不让你再进行强制类型转换的,这是矛盾的,所以不能加入信息 }}
0 0
- Java泛型详解
- 泛型详解
- java泛型详解
- C#泛型详解
- C#泛型详解
- java泛型详解
- Java泛型详解
- C#泛型详解
- Java泛型详解
- java泛型详解
- 泛型详解
- Java泛型详解
- C#泛型详解
- C#泛型详解
- java泛型详解
- 泛型详解
- java 泛型详解
- java 泛型详解
- 122. Best Time to Buy and Sell Stock II
- psmisc工具
- 可重入函数与线程安全的区别和联系
- Spring源码学习之BeanFactory和FactoryBean
- jvm-监控指令-jstack
- 泛型详解
- Xcode8升级遇到的问题
- 论文笔记(一)Deep Ranking for Person Re-Identification via Joint Representation Learning (续)
- 绝对地址赋值
- 分布式消息系统:Kafka
- 【Java基础】Number类
- 笔记——Activity启动模式
- VS2013 strcpy 报错的3种处理方法
- C++11中的std::function