设为首页收藏本站

EPS数据狗论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1992|回复: 0

[java] Java 10 的 5 件事

[复制链接]

88

主题

1844

金钱

2283

积分

中级用户

发表于 2018-4-26 09:29:31 | 显示全部楼层 |阅读模式
1. Java的新版本节奏
从历史上看,JDK发行的节奏是由大的新特性驱动的。作为最近的例子,Java 8以lambda和流的形式引入了函数式编程,而Java 9引入了模块化Java系统。每个新版本都被热切地期待着,但是次要的修复程序经常束之高阁,等待更大的组件版本被最终确定。Java的进化落后于其他语言。
新的高频节奏将Java以更小的增量向前推进。在发布日期准备好的特性将被包括在内,而那些不能被安排在下一个版本中,就在6个月之后。在这个新周期下的第一个Java版本是Java 9,它于2017年10月发布。Java 10于2018年3月发布,Java 11将于2018年9月发布。



作为新节奏的一部分,甲骨文表示,它将只支持每个主要版本,直到下一个主要版本发布为止。 当Java 11发布时,Oracle将停止支持Java 10。支持Java版本的开发人员必须每6个月迁移一次主要版本。 不希望或不需要频繁迁移的开发人员可以使用LTS(长期支持)版本,该版本每三年更新一次。 目前的LTS版本Java 8将在今年秋季发布Java 11之前得到支持。
2. 局部变量类型推断
局部变量类型推断是Java 10中最显着的特性。在进入JDK 10之前,争论非常激烈,该特性允许编译器推断局部变量的类型,而不是要求程序员明确指定它。
清单1 显示了如何在Java 10之前定义一个String变量类型。








清单1.声明并分配一个String类型的变量
String name = "Alex"
清单2展示了在Java10中定义与String类型相同的变量
清单2.用局部变量类型推断String类型的变量
var name = "Alex";
正如你看到的,唯一的区别就是使用了var保留类型名称。使用右边的表达式,编译器可以将变量名的类型推断为String。
这看起来有点简单,让我们来看一个更加复杂的例子。如果一个变量分配给了调用方法的返回值是怎样的?在这种情况下,编译器可以根据方法的返回类型推断变量的类型,如清单3所示。



清单3.从返回类型推断String类型
var name = getName();String getName(){    return "Alex";}使用局部变量类型
顾名思义,局部变量类型推断功能仅适用于局部变量。 它不能用于定义实例或类变量,也不能用于方法参数或返回类型。 但是,您可以在类和增强型循环中使用var,可以从迭代器中推断出类型,如清单4所示。



清单4.在循环中使用var
for(var book : books){}for(var i = 0; i < 10; i++){}
使用这种类型的最明显的原因是为了减少代码中的冗长。 看看清单5中的示例。
清单5.很长的类型名称使得代码很长
String message = "Incy wincy spider...";StringReader reader = new StringReader(message);StreamTokenizer tokenizer = new StreamTokenizer(reader);
请注意,使用var保留类型名称重写清单5时发生了什么。
清单6. var类型减少了代码的冗长性
var message = "Incy wincy spider...";var reader = new StringReader(message);var tokenizer = new StreamTokenizer(reader);
清单6中的类型声明是垂直排列的,并且在构造函数调用的右侧每个申明中都会提到一次类型。 想象一下使用这种类型在一些Java框架中常见的长类名的好处。



局部变量类型的问题1. var掩盖了类型
你已经看到了var如何提高代码的可读性,但是从另一方面来看,它也可以掩盖它。 看看清单7中的示例。

清单7.返回类型不清楚
var result = searchService.retrieveTopResult();
在清单7中,我们必须猜测返回类型。 让读者猜测发生了什么的代码是难以维护的。



2. var不能与lambda一起使用
与lambda表达式一起使用时,类型推断效果不佳,主要原因是编译器缺少类型信息。 清单8中的lambda表达式不会被编译。

清单8.类型信息不足
Function<String, String> quotify = m -> "'" + message + "'";var quotify = m -> "'" + message + "'";
在清单8中,编译器的右边表达式中没有足够的类型信息来推断变量类型。 Lambda语句必须始终声明一个显式类型。



3. var不会与菱形操作符混在一起
与菱形操作符一起使用时,类型推断也不能很好地工作。 看看清单9中的例子。

清单9.使用带有var的菱形运算符
var books = new ArrayList <>();亲自尝试一下
想要亲自尝试本地变量类型推断,您需要下载JDK 10和一个支持它的IDE。 IntelliJ的EAP(Early Access Program)版本具有此支持。 一旦你下载并安装了它,你可以从本文附带的GitHub存储库中检出代码开始。 你会在那里找到局部变量类型推断的例子



在代码清单9中,books的ArrayList的参数类型是什么呢?你可能明白你是希望ArrayList存储一个书的列表,但是编译器不能推断出来。反之,编译器会做的唯一它能做的事情,就是推断出来这是一个参数是Object类型ArrayList:ArrayList<Object>()。
另外一种方法就是在右端表达式中的菱形运算符中定义具体类型。然后你可以让编译器从而推断出来变量的类型,就像在代码清单10中写的一样。或者使用另外一种方式,即你必须明确地以传统方式声明变量:List<Book> books。事实上,你可能更喜欢这种方式,因为它能让你定义一个抽象类型,并对List接口编程:
清单10. 定义出具体类型
var books = new ArrayList<Book>();
3、增加、删除和弃用删除
Java 10删除了很多工具:
  • 命令行工具javah,可以使用javac -h代替。
  • 命令行选项-X:prof,尽管可以使用jmap工具来访问分析信息。
  • 政策工具。

一些从Java1.2开始标记的为已弃用的API也被永久删除了。包括java.lang.SecurityManager.inCheck字段和以下方法:
  • java.lang.SecurityManager.classDepth(java.lang.String)
  • java.lang.SecurityManager.classLoaderDepth()
  • java.lang.SecurityManager.currentClassLoader()
  • java.lang.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)




弃用
JDK 10也弃用了一些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()方法也被弃用。
添加和包含
作为Oracle JDK和Open JDK正在进行对接的一部分,Open JDK现在包含Oracle JDK中可用的一部分根证书颁发机构。这些包括Java Flight Recorder和Java Mission Control。此外,JDK 10在java.text,java.time和java.util包的适当位置中增加了对BCP 47语言标记的Unicode扩展的增强支持。另一项新功能允许在不执行全局VM安全点的情况下执行线程回调。这使停止单个线程既可行又便宜,而不是要求你停止所有线程或不需要任何线程。





4.提高容器意识
如果你部署到像Docker这样的容器,那么这个功能特别适合你。 现在JVM意识到它正在容器中运行,并查询容器中可用处理器的数量,而不是查询主机操作系统。 也可以从外部附加到在容器中运行的Java进程,这使监视JVM进程变得更加容易。
以前,JVM不知道它的容器,并会向主机操作系统询问活动CPU的数量。 在某些情况下,这会导致JVM过度报告资源,导致多个容器在同一操作系统上运行时出现问题。 在Java 10中,您可以将容器配置为使用主机操作系统的CPU的子集,并且JVM将能够确定正在使用的CPU数量。 您还可以使用-XX:ActiveProcessorCount标志明确指明能够看到的容器化JVM处理器数量。



5.应用程序类数据共享
此特性的用途是提高运行间和多个运行相同代码的JVM启动时间,同时减少内存占用量。 这通过在JVM之间共享关于类的元数据来实现。 JVM的第一次运行收集并归档有关它所加载的类的数据。 然后它将数据文件提供给其他JVM以及该JVM的后续运行,从而节省JVM初始化过程中的时间和资源。 类数据共享实际上已经有一段时间了,但仅限于系统类。 现在这个功能已经扩展到包含所有的应用程序类。



结束语
Java10中头号特性是把Var作为了新的类型名,它可以让代码更加简洁和清晰。但是,如果使用不谨慎也会掩盖住原来的含义和意图。当不明确含义的时候,IDE或许可以帮助你辨别类型,但是在一个IDE中无法读取所有类型的代码。我们经常通过GitHub仓库、调试器或者代码审查工具在线阅读代码。开发者使用这个新的特性时,务必注意为了将来的读者和维护人员提高代码可读性。

Java的新版本如此高频率发布是一个值得欢迎的改变。在发布日期,已经准备好的特性必须发布,那些延迟的特性将在短暂的调整之后再下个版本发布。新的循环将加快java的发展进程,那些已经开发完成并且已经列出来的特性,开发者不需要等好多年。从一个主要版本到下一个主要版本的发布的支持时间越来越短,这带来一些合理的担忧,但是LTS应该可以有效的缓解该问题。发布疲劳是另一个风险,因为开发者对频繁的版本更新感到厌烦。总的来说,我认为这是一个积极的行为,在未来很长的一段时间里,它有助于保证java的活跃度和维持java的发展。







您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

客服中心
关闭
在线时间:
周一~周五
8:30-17:30
QQ群:
653541906
联系电话:
010-85786021-8017
在线咨询
客服中心

意见反馈|网站地图|手机版|小黑屋|EPS数据狗论坛 ( 京ICP备09019565号-3 )   

Powered by BFIT! X3.4

© 2008-2028 BFIT Inc.

快速回复 返回顶部 返回列表