Java 泛型,了解这些就够用了。
? 此文目录:
? 一、Java泛型是什么?
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
通俗的讲,泛型就是操作类型的 占位符,即:假设占位符为T,那么此次声明的数据结构操作的数据类型为T类型。 ? 二、通常的泛型写法示例
泛型类定义: public class ApiResult<T> { 定义泛型方法:
class JsonUtil { public <T> T str2Json(String jsonText,Class target){ T result=null; //....parse to json return result; } } ? ? 使用: ? //泛型类使用 ApiResult<List<User>> result2=new ApiResult<List<User>>(); ? ApiResult<Integer> result3=new ApiResult<Integer>(); //泛型方法使用 String userJsonText="....省略",dogJsonText="....省略";;
定义: class ResultMap<K,V> { private K key; V value; //省略 set,get 方法 使用: ResultMap<String,User> resultMap=new ResultMap<>(); resultMap.put("currentUserKey",new User());
<? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类
<? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object
三、类型擦除 先看一个例子,Operate类如下: Operate { static main(String[] args) { List<String> names=new ArrayList<String>(); names.add("Jack"); names.add("Tom"); names.add("peter"); for(String name:names){ System.out.println("wellcome:"+name); } } } 其对应的class文件反编译之后,我们使用java-gui反编译.exe ?查看编译之后的代码如下 发现没有,根本没有<String> 这一部分了。这个限制为String类型的泛型被“擦除”了。写代码的时候,泛型会做校验,类型不对应的,无法add,但是编译之后边去掉了泛型类型。 ? ? 四、什么要使用Java泛型 ?在上面 第三部分介绍了“类型擦除”之后,在来说为什么要使用Java泛型就比较好说了。这里的泛型就相当于“约法三章”,先给你定好“规矩”,我这个List<String> 就是用来操作 String类型的,你插入Person对象就不行。说白了就是为了类型安全。所以其好处有: ? 类型安全:通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。 消除强制类型转换: 该代码不使用泛型: List li = new ArrayList(); li.put(new Integer(3)); Integer i = (Integer) li.get(0); 该代码使用泛型: List<Integer> li = new ArrayList<Integer>(); li.put()); Integer i = li.get(0); ? ? 了解了上面的这么多,已经足够日常使用泛型了。下面了解下PECS原则 五、PECS原则 ? 先看例子: 此处定义三个类,spiring,summer继承season List<? extends Season> list1=new ArrayList<>(); list1.add(new Spring());这里编译不通过,因为编译器无法确定list所持有的类型。 List<? extends Season> list2=new ArrayList<Spring>();
// list2.add(new Spring());//也是无法通过编译
//通过上文,我们知道 ?extends Season表示可以接收的类型为 Seaon 或者其子类。 ? List<? super Season> sea=(); sea.add(ok sea.add(new Summer());new Season()); sea.add(new Object());error List<? (); spring.add(error 这里 ,PECS原则 如下: 如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? 通配符;(Producer Extends) 如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer Super) 如果既要存又要取,那么就不要使用任何通配符。 ? ? ? Java Queue系列之PriorityQueue 一篇图看清Java中的各种Queue ? [spring如何启动的?这里结合spring源码描述了启动过程](https://www.cnblogs.com/demingblog/p/7443714.html) [Mybatis Mapper接口是如何找到实现类的-源码分析](https://www.cnblogs.com/demingblog/p/9544774.html) ? [Docker & k8s 系列一:快速上手docker](https://www.cnblogs.com/demingblog/p/12905545.html) ? (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |