Java 泛型编程分析
发布时间:2021-12-13 11:30:51 所属栏目:教程 来源:互联网
导读:Technorati 标记: Java,泛型,generic java泛型应用是java核心基础之一,从java 5开始引进泛型。如果你曾经使用过java Collection,那你已经算是接触过泛型了。在java Collection里使用泛型是一件很简单的事情,可泛型还具有很多你意想不到的作用。在深入了解
Technorati 标记: Java,泛型,generic java泛型应用是java核心基础之一,从java 5开始引进泛型。如果你曾经使用过java Collection,那你已经算是接触过泛型了。在java Collection里使用泛型是一件很简单的事情,可泛型还具有很多你意想不到的作用。在深入了解泛型之前,首先来了解一下泛型的一些基本概念与原理。 一、java 泛型引入 java泛型的应用可以提高的代码的复用性,同时泛型提供了类型检查,减少了数据的类型转换,同时保证了类型安全。下面看一下,泛型如何保证了类型安全: List list = new ArrayList(); list.add("abc"); list.add(new Integer(1)); //可以通过编译 for (Object object : list) { System.out.println((String)object);//抛出ClassCastException异常 } 上面的代码会在运行时抛出ClassCastException,因为它尝试将一个Integer转换为String。接着,来看一下从java5开始,Collection的用法: List<String> list = new ArrayList<>(); list.add("abc"); //list.add(new Integer(1)); //编译错误 for (String string : list) { System.out.println(string);//无需任何强制类型转换 } 注意到,List的创建增加了类型参数String,因此只能向list添加String类型对象,添加其他对象会抛出编译异常;同样可以注意到,foreach循环不需要再添加任何强制类型转换,也就移除了运行时的ClassCastException异常。 二、泛型的类与接口 既然是学泛型,自然就要知道如何去使用泛型定义自己的类和接口。同时为了加深理解泛型的作用,先引进一个原始的类: public class Gen { private Object obj; public Object getObj() { return obj; } public void setObj(Object obj) { this.obj = obj; } public static void main(String[] args) { Gen gen = new Gen(); gen.setObj("abc"); String str = (String) gen.getObj();//类型转换,可能会引起运行时ClassCastException } } 原始类的定义,容易引发ClassCastException,和第一大点谈到的类似。现在来看一下泛型类来重新定义Gen — 使用<>指定泛型参数,如下: public class Gen<T> { T obj; public T getObj() { return obj; } public void setObj(T obj) { this.obj = obj; } public static void main(String[] args) { Gen<String> gen = new Gen<>(); gen.setObj("abc"); // gen.setObj(10); //无法通过编译 String str = gen.getObj(); //无需类型转换 //----------------------------- Gen gen2 = new Gen();//raw type原始类型 gen2.setObj("abc"); gen2.setObj(10); //可以通过编译,自动装箱将10转化为Integer对象 Integer num = (Integer) gen2.getObj();//使用了强制类型转换 } } 细心的你会发现在main()方法里是使用泛型类型Gen<String>,便不再需要强制类型转换,也就移除了运行时的ClassCastException。同时为了区别,在此也定义了一个没有使用泛型类型的gen2,这时,编译器会弹出一个警告“Gen is a raw type,References to generic type Gen<T> should be parameterized”。当我们不提供泛型类型时,会默认使用Object会代替,也是因此这样,gen2可以设置String和Integer类型,不过,我们应尽量去避免这种这种情况的出现,如此,便又需要用到强制类型转换,也伴随着运行时的ClassCastException异常。 tips:可以使用@SuppressWarnings("rawtypes")来抑制编译器弹出警告。 接口的泛型应用和类的泛型应用很类似,如下: public interface List <E> { void add(E x); Iterator<E> iterator(); } public interface Iterator<E> { E next(); boolean hasNext(); } 类似的,可以将此应用到自定义的接口与类当中。另外再提一下的是,可以使用多个泛型参数来定义接口与类,比如Map<K,V>;同时,泛型类型也可以作为一个参数来用,如下:new HashMap<String, List<String>>()。 ![]() (编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |