Java8中对泛型目标类型推断方法的改进

 更新时间:2014年06月09日 11:48:44   作者:  
这篇文章主要介绍了Java8中对泛型目标类型推断方法的改进,需要的朋友可以参考下

一、简单理解泛型

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。通俗点将就是“类型的变量”。这种类型变量可以用在类、接口和方法的创建中。

理解Java泛型最简单的方法是把它看成一种便捷语法,能节省你某些Java类型转换(casting)上的操作:

复制代码 代码如下:
List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple apple =box.get(0);

上面的代码自身已表达的很清楚:box是一个装有Apple对象的List。get方法返回一个Apple对象实例,这个过程不需要进行类型转换。没有泛型,上面的代码需要写成这样:
复制代码 代码如下:
Apple apple = (Apple)box.get(0);

二、泛型的尴尬

泛型的最大优点是提供了程序的类型安全同时可以向后兼容,但也有尴尬的地方,就是每次定义时都要写明泛型的类型,这样显示指定不仅感觉有些冗长,最主要是很多程序员不熟悉泛型,因此很多时候不能够给出正确的类型参数,现在通过编译器自动推断泛型的参数类型,能够减少这样的情况,并提高代码可读性。


三、java7的泛型类型推断改进

在以前的版本中使用泛型类型,需要在声明并赋值的时候,两侧都加上泛型类型。例如:

复制代码 代码如下:
Map<String, String> myMap = new HashMap<String, String>();

你可能觉得:老子在声明变量的的时候已经指明了参数类型,为毛还要在初始化对象时再指定?幸好,在Java SE 7中,这种方式得以改进,现在你可以使用如下语句进行声明并赋值:
复制代码 代码如下:
Map<String, String> myMap = new HashMap<>(); //注意后面的"<>"

在这条语句中,编译器会根据变量声明时的泛型类型自动推断出实例化HashMap时的泛型类型。再次提醒一定要注意new HashMap后面的“<>”,只有加上这个“<>”才表示是自动类型推断,否则就是非泛型类型的HashMap,并且在使用编译器编译源代码时会给出一个警告提示。

但是:Java SE 7在创建泛型实例时的类型推断是有限制的:只有构造器的参数化类型在上下文中被显著的声明了,才可以使用类型推断,否则不行。例如:下面的例子在java 7无法正确编译(但现在在java8里面可以编译,因为根据方法参数来自动推断泛型的类型):

复制代码 代码如下:

List<String> list = new ArrayList<>();
list.add("A");// 由于addAll期望获得Collection<? extends String>类型的参数,因此下面的语句无法通过
list.addAll(new ArrayList<>());


四、Java8的泛型类型推断改进

java8里面泛型的目标类型推断主要2个:

1.支持通过方法上下文推断泛型目标类型
2.支持在方法调用链路当中,泛型类型推断传递到最后一个方法
让我们看看官网的例子:

复制代码 代码如下:

class List<E> {
   static <Z> List<Z> nil() { ... };
   static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
   E head() { ... }
}

 根据JEP101的特性,我们在调用上面方法的时候可以这样写

复制代码 代码如下:

//通过方法赋值的目标参数来自动推断泛型的类型
List<String> l = List.nil();
//而不是显示的指定类型
//List<String> l = List.<String>nil();
//通过前面方法参数类型推断泛型的类型
List.cons(42, List.nil());
//而不是显示的指定类型
//List.cons(42, List.<Integer>nil());

五、总结

以上是JEP101的特性内容了,Java作为静态语言的代表者,可以说类型系统相当丰富。导致类型间互相转换的问题困扰着每个java程序员,通过编译器自动推断类型的东西可以稍微缓解一下类型转换太复杂的问题。 虽然说是小进步,但对于我们天天写代码的程序员,肯定能带来巨大的作用,至少心情更愉悦了~~说不定在java 9里面,我们会得到一个通用的类型var,像js或者scala的一些动态语言那样^_^

相关文章

  • 详解SpringMVC学习系列之国际化

    详解SpringMVC学习系列之国际化

    这篇文章主要介绍了详解SpringMVC学习系列之国际化,详细的介绍了关于浏览器,Session,Cookie,URL请求的国际化的实现,有兴趣的可以了解一下
    2017-07-07
  • MybatisPlus保存、读取MySQL中的json字段失败问题及解决

    MybatisPlus保存、读取MySQL中的json字段失败问题及解决

    这篇文章主要介绍了MybatisPlus保存、读取MySQL中的json字段失败问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 详解Java并发工具类之CountDownLatch和CyclicBarrier

    详解Java并发工具类之CountDownLatch和CyclicBarrier

    在JDK的并发包中,有几个非常有用的并发工具类,它们分别是:CountDownLatch、CyclicBarrier、Semaphore和Exchanger,本文主要来讲讲其中CountDownLatch和CyclicBarrier的使用,感兴趣的可以了解一下
    2023-06-06
  • Java中的functor实现

    Java中的functor实现

    Java中的functor实现...
    2006-12-12
  • Java全面细致讲解Cookie与Session及kaptcha验证码的使用

    Java全面细致讲解Cookie与Session及kaptcha验证码的使用

    web开发阶段我们主要是浏览器和服务器之间来进行交互。浏览器和服务器之间的交互就像人和人之间进行交流一样,但是对于机器来说,在一次请求之间只是会携带着本次请求的数据的,但是可能多次请求之间是会有联系的,所以提供了会话机制
    2022-06-06
  • 如何设置springboot启动端口

    如何设置springboot启动端口

    spring boot是个好东西,可以不用容器直接在main方法中启动,而且无需配置文件,方便快速搭建环境。下面给大家介绍springboot启动端口的设置方法和spring boot创建应用端口冲突8080 问题,感兴趣的朋友一起看看吧
    2017-08-08
  • Spring Boot整合Zookeeper实现分布式锁的场景分析

    Spring Boot整合Zookeeper实现分布式锁的场景分析

    这篇文章主要介绍了Spring Boot整合Zookeeper实现分布式锁,zk实现分布式锁完全是依靠zk节点类型当中的临时序号节点来实现的,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • 如何通过一个注解实现MyBatis字段加解密

    如何通过一个注解实现MyBatis字段加解密

    用户隐私很重要,因此很多公司开始做数据加减密改造,下面这篇文章主要给大家介绍了关于如何通过一个注解实现MyBatis字段加解密的相关资料,需要的朋友可以参考下
    2022-02-02
  • Java切割字符串的踩坑实战记录

    Java切割字符串的踩坑实战记录

    最近在项目中使用了java中的分割字符串,踩了一个坑,充分了展示了自己对java底层的认知有很多的不足和欠缺,下面这篇文章主要给大家介绍了关于Java切割字符串的踩坑实战记录,需要的朋友可以参考下
    2022-11-11
  • JavaEE7+Websockets+GlassFish4打造聊天室

    JavaEE7+Websockets+GlassFish4打造聊天室

    Java EE 7已经发布很久了,新增加了很多新的功能和特性,如新增或更新了不少的JSR标准。其中特别受到关注的是Websockets。它的一个好处之一是减少了不必要的网络流量。它主要是用于在客户机和服务器之间建立单一的双向连接。
    2015-09-09

最新评论