9

JAVA 10 新特性 - 局部变量推断

 3 years ago
source link: https://minei.me/archives/540.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

JAVA 10 新特性 - 局部变量推断

boyizmen
2020-04-14

Java 10 添加了一个非常重要的新特性:局部变量类型推断。

在声明局部变量的时候使用下面的方式:

  1. var intValue = 1;
  2. var doubleValue = 1.1;
  3. var stringValue = "string";
  4. var list = new ArrayList<>();
  5. var map = new HashMap<>();

局部变量推断使用的是 var ,同时 var 并不是一个关键词,而是一个保留类型名,所有使用var进行命名的方法、属性、变量都不会受到任何影响;但是使用var命名的类名和接口会受到影响,如果是新建类或者接口使用var则会编译不通过。后者其实可以忽略,因为类名和接口命名都是遵循的驼峰,刚好规避了var这个单词。

就从编码上来说,代码上会简洁不少,少了挺多的冗余代码。但是有好处就有坏处,代码的可读性比以前低,无法直观的看到变量类型,如果存在大量局部变量的调用和声明代码读起来可能就不太舒服了。不过个人觉得是提升了不少效率,再也不用显示声明变量类型了。

变量推断可以使用的场景:

  • 局部变量的初始化,不能使用 var 进行不初始化的声明;
    比如:
    1. var a;
  • for循环(包括for-each)迭代中的索引和迭代元素引用(其实也算是局部变量);

同时需要注意下面几点:

  • 无法从null值中推断,也就是说如果声明的地方有隐式的null值会抛出空指针;
    比如:
    1. public void loop(List<Integer> ints) {
    2. for(var i : ints) {
    3. // ...do something
    4. // 调用会直接抛出空指针
    5. loop(Arrays.asList(1, null, 2, 4))
  • 无法使用在方法中、构造器、返回值、属性声明、异常处理和其他变量初始化场景,可以直接直接理解成只能使用在局部变量上;
    比如下面的代码:
    1. public var test(var p1, var p2) {...}
  • 无法推断未初始化的变量;

看下上面代码的class文件反编译后的代码:

  1. int intValue = true;
  2. double doubleValue = 1.1D;
  3. String stringValue = "string";
  4. new ArrayList();
  5. new HashMap();

编译完后的class中其实已经是正确的类型了,可以知道类型推断是发生在编译期的,在编译期间,编译器会执行推断进行类型转换,如果变量为null则会抛出空指针异常。
可以看到其实局部变量推断是一种新的语法糖,jvm是不认识这个东西的,整个推断过程都是发生在编译期,jvm不需要任何的改动来支持这个特性。

参考文档:
https://openjdk.java.net/jeps/286


整个Java10的新特性看了一遍,也就这个是个比较大的改动,并且是直接对编码上有着不少的效率提升。

版权所有丨转载请注明出处:https://minei.me/archives/540.html


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK