摘要:实际上并未引入太多新特性,不过有一个新特性最引人注目等了这么久终于支持类型推断了,那么今天就来看一看的类型推断,和其他语言相比有哪些异同吧。本次更新也支持了类型推断,对于这种重量级语言来说还是一件值得高兴的事。
0x01 Java 10简介
自从有了校内的下载网站,很少上Oracle官网下载JDK了,结果前两天听钟神说Java 10都出来了2333。干IT这行还真是要与时俱进啊,那就来看一下Java 10吧。
Java 10实际上并未引入太多新特性,不过有一个新特性最引人注目:
JEP 286: Local-Variable Type Inference
等了这么久Java终于支持类型推断了,那么今天就来看一看Java 10的类型推断,和其他语言相比有哪些异同吧。
0x02 类型推断概述类型推断是新型的高级语言提供的一类功能,允许根据编译上下文来推断变量的类型,不需要自己手动写类型,使得代码更加简洁。
目前我接触的编程语言中,JavaScript、Swift和Python都支持这种语法。本次Java 10更新也支持了类型推断,对于Java这种重量级语言来说还是一件值得高兴的事。
0x03 体验Java 10的类型推断功能让我们写一段Base64编码的代码,体验一下Java 10的类型推断功能:
//Java代码 import java.util.Base64; class Untitled { public static void main(String[] args) { var b64encoder = Base64.getEncoder(); var encodeString = b64encoder.encodeToString("Hello World".getBytes()); System.out.println(encodeString); } }
初步体验还是不错的,只是我的IDE还没有升级,还不支持自动提示这种语法。甚至Eclipse还不能正常编译Java 10的代码,我只能手动通过javac来编译。整体而言Java 10的类型推断功能是类似于Swift/JavaScript的,需要写var关键字,并不像是Python那样的使用方式。
0x04 Java 10类型推断的不足上面的用法看起来很友好,那么有没有更自由的写法呢?很快的我就收到了编译器错误:
//Java代码 import java.util.Base64; class Untitled { public static void main(String[] args) { var b64encoder = Base64.getEncoder(); var encodeString = b64encoder.encodeToString("Hello World".getBytes()); System.out.println(encodeString); var a = 1,b = 2; } }
错误: "var" 不允许在复合声明中使用 var a = 1,b = 2; ^ 1 个错误
看来Java 10的类型推断还是有诸多限制和不便,不像其他语言那般好用,对比一下Swift语言:
//Swift代码 import Foundation let string = "Hello World" let data = string.data(using: String.Encoding.utf8)! let encodeString = data.base64EncodedString() print(encodeString) var a = 1, b = 2;
比如说Java 10并没有let关键字,也就是说,并不能快速的使用类型推断定义常量。同时也不能一次用var定义多个变量,当同类型变量较多的时候,我觉得还不如把类型写出来。
同时,根据官方的说明,你也不能将var用于成员变量,只能用于局部变量,例如下面的例子会出现编译错误:
//Java代码 import java.util.Base64; class Untitled { class Student { var name = ""; Student(String name) { this.name = name; } } public static void main(String[] args) { var b64encoder = Base64.getEncoder(); var encodeString = b64encoder.encodeToString("Hello World".getBytes()); System.out.println(encodeString); } }
错误: 此处不允许使用 "var" var name = ""; ^ 1 个错误
而在其他语言中,你可以更自由的使用var,在任何你想要的地方,只要不引起歧义:
//Swift代码 import Foundation class Student { var name = ""; init(name: String) { self.name = name; } } var string = "Hello World" let data = string.data(using: String.Encoding.utf8)! let encodeString = data.base64EncodedString() print(encodeString)
作为对比,Swift比Java 10在类型推断方面更加灵活,同时二者也有共同点——它们都是强类型语言,任何变量必须具有某种类型,所谓的类型推断只是一种语法上的精简。例如你不能像Python一样在形参列表中也不使用参数类型,或者直接省略返回值类型,这些类型还都是必须的:
#Python代码 def printNumber(num): print(num) return 1 retCode = printNumber(4) print(retCode)
//Swift代码 func printNumber(num: Int) -> Int { print(num) return 1 } let retCode = printNumber(num: 2) print(retCode)
//Java代码 import java.util.Base64; class Untitled { public static int printNumber(int num) { System.out.println(num); return 1; } public static void main(String[] args) { var retCode = printNumber(3); System.out.println(retCode); } }0x05 总结
经过简单的体验,基本清楚了Java 10的类型推断功能。以后在局部范围定义对象,可以有了更简略的写法:
//Before Java 9 MessageDigest md = MessageDigest.getInstance("SHA-512"); //Java 10 var md = MessageDigest.getInstance("SHA-512");
显然这种代码不兼容早期版本的Java,即使你将Java 10的代码编译为字节码,也不能在低版本的JVM上运行。这种新语法也不能用于Android开发等用途。比如我使用OpenJDK 1.8来测试我们前面编码base64的代码,就出现了异常:
$ java -version java version "10" 2018-03-20 Java(TM) SE Runtime Environment 18.3 (build 10+46) Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode) $ java Main SGVsbG8gV29ybGQ=
# java -version openjdk version "1.8.0_111" OpenJDK Runtime Environment (IcedTea 3.2.0) (suse-33.1-x86_64) OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode) # java Main Error: A JNI error has occurred, please check your installation and try again Exception in thread "main" java.lang.UnsupportedClassVersionError: Main has been compiled by a more recent version of the Java Runtime (class file version 54.0), this version of the Java Runtime only recognizes class file versions up to 52.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) at java.net.URLClassLoader.access$100(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:368) at java.net.URLClassLoader$1.run(URLClassLoader.java:362) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:361) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)
所以说这种新语法还是不够灵活,同时兼容性也堪忧,但是聊胜于无。同时也会一定程度上减少Java代码的长度,让编程更加优雅一些。同学们如果想体验一下新语法,可以升级到Java 10,不过好多Java应用都不兼容,所以升级还是需慎重啊!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/71177.html
摘要:目标发布目前有两个主要功能针对局部变量类型推断这将删除大部分对象实例化所需的冗长的包含手动类型信息整合源树的库即不同的库将被合并成一个单一的存储库。特别是,承诺为局部变量实例化引入类型推断机制,并将现有的存储库合并到一个存储库中。 JDK 10 何时发布? JDK 10 是 Java 10 标准版的部分实现,将于 2018 年 3 月 20 日发布,改进的关键点包括一个本地类型推断、一...
摘要:的新特性说了这么多,看都会有哪些特性来改变我们写代码的方式呢局部变量类型推断局部变量类型推断可以说是中最值得注意的特性,这是语言开发人员为了简化应用程序的编写而采取的又一步,如下图所示。 showImg(https://segmentfault.com/img/remote/1460000015356980); Java 9才发布几个月,很多玩意都没整明白,现在Java 10又快要来了...
摘要:就等于局部变量类型推断使用示例既然叫局部变量类型推断,以只能用在局部变量中,下面给出更多使用示例。,本次局部变量类型推断实战文章就到这里了,后续带来更多的的实战方面的文章。 现在 Java 9 被遗弃了直接升级到了 Java 10,之前也发过 Java 10 新特性的文章,现在是开始实战 Java 10 的时候了。 今天要实战的是 Java 10 中最重要的特性:局部变量类型推断,大家...
摘要:美国时间月日,正式发布了,这是据以后支持的首个长期版本。加强是中的新特性,开始对增加了以下个新方法。结束语现在许多人还在使用或者,不过在年初就会结束免费更新。 美国时间 09 月 25 日,Oralce 正式发布了 Java 11,这是据 Java 8 以后支持的首个长期版本。 为什么说是长期版本,看下面的官方发布的支持路线图表。 showImg(https://segmentfaul...
阅读 2810·2023-04-25 17:59
阅读 657·2023-04-25 15:05
阅读 617·2021-11-25 09:43
阅读 3009·2021-10-12 10:13
阅读 3513·2021-09-27 13:59
阅读 3522·2021-09-23 11:21
阅读 3774·2021-09-08 09:35
阅读 541·2019-08-29 17:12