当前位置: 首页 > 科技观察

Java10的5个最重要的新特性!

时间:2023-03-15 19:29:03 科技观察

局部变量类型推断是一个备受争议的话题,但Java10为JVM中的垃圾收集和容器感知带来了可喜的变化。关于本系列您认为您了解Java编程吗?事实上,大多数开发人员只是触及Java平台的皮毛,学习只是为了完成他们的工作。在这个正在进行的系列中,JavaTechnologies深入探讨了Java平台的核心功能,提供了可以帮助您解决最棘手的编程挑战的提示和技巧。Java?开发人员习惯于等待新Java版本的发布,但新的高频发布节奏改变了这一点。在Java9发布仅6个月后,现在Java10正在敲门。再过6个月,我们将拥有Java11。一些开发人员可能会觉得这种快速发布是多余的,但新的节奏标志着长期需要的改变。与其版本号一样,Java10提供了10个新特性,本文介绍了我认为最重要的5个特性(您可以在OpenJDK10项目页面上查看它们)。Java的新版本节奏从历史上看,JDK发布的节奏一直由重要的新功能驱动。作为最近的示例,Java8以lambda和流的形式引入了函数式编程,而Java9引入了模块化Java系统。每个新版本都备受期待,但小修复通常会被搁置,等待更大的组件版本完成。Java的发展落后于其他语言。一种新的高频节奏以较小的增量推动Java向前发展。将包括在发布日期前就绪的功能,而无法安排在仅6个月后的下一个版本中发布的功能。这个新周期下的第一个Java版本是Java9,它于2017年10月发布。Java10于2018年3月发布,Java11将于2018年9月发布。作为新节奏的一部分,Oracle表示将只支持每个主要版本直到下一个主要版本。Java11发布后,Oracle将停止支持Java10。支持Java版本的开发人员必须每6个月迁移一次主要版本。不想或不需要频繁迁移的开发人员可以使用每三年更新一次的LTS(长期支持)版本。当前的LTS版本Java8将在今年秋天发布Java11之前得到支持。局部变量类型推断局部变量类型推断是Java10中最显着的特性。争论一直持续到JDK10,该特性允许编译器推断局部变量的类型,而不需要程序员显式指定它。清单1显示了如何在Java10之前定义String变量类型。清单1.声明和分配类型为StringStringname="Alex"的变量清单2显示了Java10中String类型变量的定义清单2.推断变量具有局部变量类型varname="Alex"的String类型;如您所见,唯一的区别是使用了var保留类型名称。使用右边的表达式,编译器可以推断出变量名的类型为String。这看起来有点简单,那么让我们看一个更复杂的例子。如果一个变量赋值给调用方法的返回值怎么办?在这种情况下,编译器可以从方法的返回类型推断变量的类型,如清单3所示。清单3.从返回类型推断String类型varname=getName();StringgetName(){return"Alex";}使用局部变量类型顾名思义,局部变量类型推断仅适用于局部变量。它不能用于定义实例或类变量,也不能用于方法参数或返回类型。但是,您可以在类和增强循环中使用var,并且可以从迭代器中推断出类型,如清单4所示。清单4.在循环中使用varfor(varbook:books){}for(vari=0;i<10;i++){}使用这种类型最明显的原因是减少代码的冗长。看一下清单5中的示例。清单5.很长的类型名称使代码很长什么。清单6.var类型减少了代码的冗长该类型在.右侧的每个声明中被提及一次。想象一下使用这种在某些Java框架中很常见的长类名的好处。局部变量类型的问题1.var屏蔽类型您已经看到var如何提高代码可读性,但另一方面,它也可以屏蔽类型。查看清单7中的示例。清单7.返回类型不明确varresult=searchService.retrieveTopResult();在清单7中,我们必须猜测返回类型。让读者猜测发生了什么的代码很难维护。2.var不能与lambdas一起使用与lambda表达式一起使用时,类型推断效果不佳,主要是编译器缺少类型信息。清单8中的lambda表达式将不会被编译。清单8.类型信息不足Functionquotify=m->"'"+message+"'";varquotify=m->"'"+message+"'";在清单8中,编译器右侧的表达式公式中没有足够的类型信息来推断变量类型。Lambda语句必须始终声明显式类型。3.var不能与菱形运算符混合使用类型推断也不能很好地与菱形运算符一起使用。查看清单9中的示例。清单9.将菱形运算符与varvarbooks=newArrayList<>();结合使用亲自尝试要亲自尝试局部变量类型推断,您需要下载JDK10和支持它的IDE。IntelliJ的EAP(早期访问程序)版本具有此支持。下载并安装后,您可以从本文随附的GitHub存储库中检出代码开始。您会在那里找到局部变量类型推断的示例。在清单9中,书籍ArrayList的参数类型是什么?您可能了解您希望ArrayList存储书籍列表,但编译器无法推断出这一点。相反,编译器唯一要做的就是推断这是一个Object类型的ArrayList:ArrayList()。另一种方法是在右侧表达式中的菱形运算符中定义具体类型。然后您可以让编译器推断变量的类型,如清单10中所写。或者使用另一种方式,即您必须以传统方式显式声明变量:Listbooks。事实上,您可能更喜欢这种方法,因为它允许您针对List接口定义一个抽象类型和程序:清单10.定义一个具体类型varbooks=newArrayList();添加、删除和弃用删除Java10删除了许多工具:●命令行工具javah可以用javac-h代替。●命令行选项-X:prof,尽管jmap工具可用于访问分析信息。●政策工具。一些自Java1.2起被标记为弃用的API也被***删除。包括java.lang.SecurityManager.inCheck字段和以下方法:.SecurityManager.currentLoadedClass()java.lang.SecurityManager.getInCheck()java.lang.SecurityManager.inClass(java.lang.String)java.lang.SecurityManager.inClassLoader()java.lang.Runtime.getLocalizedInputStream(java.io.InputStream)java.lang.Runtime.getLocalizedOutputStream(java.io.OutputStream)弃用JDK10也弃用了一些API。java.security.acl包已被标记为已弃用,java.security包还包含各种相关类(Certificate、Identity、IdentityScope、Singer、auth.Policy)。此外,javax.management.remote.rmi.RMIConnectorServer类中的CREDENTIAL_TYPES被标记为已弃用。java.io.FileInputStream和java.io.FileOutputStream中的finalize()方法已被标记为已弃用。因此java.util.zip.Deflater/Inflater/ZipFileclasses中的finalize()方法也被弃用了。添加和包含作为OracleJDK和OpenJDK持续集成的一部分,OpenJDK现在包括OracleJDK中可用的根证书颁发机构的子集。其中包括JavaFlightRecorder和JavaMissionControl。此外,JDK10在java.text、java.time和java.util包中的适当位置添加了对BCP47语言标记的Unicode扩展的增强支持。另一个新功能允许在不强制执行全局VM安全点的情况下执行线程回调。这使得停止单个线程变得可行且成本低廉,而不是要求您停止所有或不停止您需要的线程。提高容器意识如果你部署到像Docker这样的容器,那么这个特性特别适合你。现在JVM知道它在容器中运行并查询容器中可用的处理器数量,而不是查询主机操作系统。还可以从外部附加到容器中运行的Java进程,这使得监控JVM进程变得更加容易。以前,JVM不知道它的容器,并会向主机操作系统询问活动CPU的数量。在某些情况下,这会导致JVM过度报告资源,从而导致多个容器在同一操作系统上运行时出现问题。在Java10中,您可以将容器配置为使用主机操作系统CPU的子集,并且JVM将能够确定正在使用多少CPU。您还可以使用-XX:ActiveProcessorCount标志来明确指示容器化JVM可以看到的处理器数量。应用程序类数据共享此功能的目的是改善运行和运行相同代码的多个JVM之间的启动时间,同时减少内存占用。这是通过在JVM之间共享有关类的元数据来实现的。JVM的第一次运行收集并归档关于它加载的类的数据。然后它使数据文件可用于其他JVM和该JVM的后续运行,从而在JVM初始化期间节省时间和资源。类数据共享实际上已经存在了一段时间,但仅限于系统类。此功能现已扩展到包括所有应用程序类。结束语Java10的头号特性是使用Var作为新的类型名称,可以让代码更加简洁明了。但是,如果不小心使用,它可能会掩盖原始含义和意图。当意思不明确时,IDE可能会帮你识别类型,但不可能在一个IDE中读取所有类型的代码。我们经常通过GitHub存储库、调试器或代码审查工具在线阅读代码。使用此新功能的开发人员必须注意为未来的读者和维护人员提高代码的可读性。Java新版本的发布频率是一个可喜的变化。在发布日期,已经准备好的功能必须发布,延迟的功能将在短时间调整后在下一个版本中发布。新的周期将加快Java开发进程,开发人员不必为已经开发和上市的功能等待数年。从一个主要版本到下一个主要版本的支持窗口越来越短,这引起了一些合理的担忧,但LTS应该可以有效缓解这种情况。发布疲劳是另一个风险,因为开发人员对频繁的版本更新感到厌烦。总的来说,我认为这是一个积极的举措,将有助于保持Java的活力并在未来很长一段时间内维持Java的发展。