查看原文
其他

Java 10 实战第 1 篇:局部变量类型推断

不羁码农 Java技术栈 2018-08-06


Java技术栈

优质的 Java 技术公众号

 


现在 Java 9 被遗弃了直接升级到了 Java 10,之前也发过 Java 10 新特性的文章,现在是开始实战 Java 10 的时候了。

今天要实战的是 Java 10 中最重要的特性:局部变量类型推断,大家都知道是 var 关键字,但具体怎么使用,及要注意什么要点呢?

我们通过几个例子来讲解局部变量类型推断这个新特性!

什么是局部变量类型推断

  1. var javastack = "javastack";

  2. System.out.println(javastack);

大家看出来了,局部变量类型推断就是左边的类型直接使用 var 定义,而不用写具体的类型,编译器能根据右边的表达式自动推断类型,如上面的 String

  1. var javastack = "javastack";

就等于:

  1. String javastack = "javastack";

局部变量类型推断使用示例

既然叫局部变量类型推断,以只能用在局部变量中,下面给出更多使用示例。

1、字面量定义局部变量

  1. private static void testVar() {

  2.    var javastack = "javastack";

  3.    System.out.println(javastack);

  4. }

2、接收方法返回值定义局部变量

  1. private static void testMethod() {

  2.    var javastack = getJavastack();

  3.    System.out.println(javastack);

  4. }

  5. public static String getJavastack() {

  6.    return "javastack";

  7. }

3、循环中定义局部变量

  1. private static void testLoop() {

  2.    for (var i = 0; i < 3; i++) {

  3.        for (var m = 10; m < 15; m++) {

  4.            System.out.println(i + m);

  5.        }

  6.    }

  7. }

4、泛型结合局部变量

  1. private static void testGeneric() {

  2.    // 表达式1

  3.    List<String> list1 = new ArrayList<>();

  4.    list1.add("javastack");

  5.    // 表达式2

  6.    var list2 = new ArrayList<>();

  7.    list2.add(2018);

  8.    // 表达式3

  9.    var list3 = new ArrayList<String>();

  10.    list3.add("javastack");

  11. }

表达式1后面 <> 里面 jdk 1.7+开始是不用带具体类型的,在接口中指明就行了。

表达式2中如果使用 var 的话, <> 里面默认会是 Object 的,所以可以添加任意类型。

表达式3中在 <> 强制使用了 String 来指定泛型。

局部变量类型推断不能用在以下场景

1、类成员变量类型

  1. // 编译报错

  2. private var javastack = "Java技术栈";

2、方法返回类型

  1. /**

  2. * 编译报错

  3. * @return

  4. */

  5. public static var getJavastack(){

  6.     return "Java技术栈";

  7. }

3、Lambda 表达式

  1. private static void testLambda() {

  2.    Runnable runnable = () -> System.out.println("javastack");

  3.    // 编译报错

  4.    // var runnable = () -> System.out.println("javastack");

  5. }

以上 3 种场景是肯定不能使用 var 的,其他场合有待验证。

局部变量类型推断优缺点

优点:简化代码

  1. CopyOnWriteArrayList list1 = new CopyOnWriteArrayList();

  2. ConcurrentModificationException cme1 = new ConcurrentModificationException();

  3. DefaultServiceUnavailableRetryStrategy strategy1 = new

  4.        DefaultServiceUnavailableRetryStrategy();

  5. var list2 = new CopyOnWriteArrayList<>();

  6. var cme2 = new ConcurrentModificationException();

  7. var strategy2 = new DefaultServiceUnavailableRetryStrategy();

从以上代码可以看出,很长的定义类型会显得代码很冗长,使用 var 大大简化了代码编写,同时类型统一显得代码很对齐。

缺点:掩盖类型

  1. var token = new JsonParserDelegate(parser).currentToken();

看以上代码,不进去看返回结果类型,谁知道返回的类型是什么?所以这种情况最好别使用 var,而使用具体的抽象类、接口或者实例类型。

var关键字原理

var其实就是 Java 10 增加的一种语法糖而已,在编译期间会自动推断实际类型,其编译后的字节码和实际类型一致,如以下例子所示。

  1. private static void testByteCode() {

  2.    String javastack1 = "javastack";

  3.    var javastack2 = "javastack";

  4. }

编译成字节码后:

  1. private static testByteCode()V

  2. L0

  3. LINENUMBER 22 L0

  4. LDC "javastack"

  5. ASTORE 0

  6. L1

  7. LINENUMBER 23 L1

  8. LDC "javastack"

  9. ASTORE 1

  10. L2

  11. LINENUMBER 24 L2

  12. RETURN

  13. L3

  14. LOCALVARIABLE javastack1 Ljava/lang/String; L1 L3 0

  15. LOCALVARIABLE javastack2 Ljava/lang/String; L2 L3 1

  16. MAXSTACK = 1

  17. MAXLOCALS = 2

可以看出 javastack1javastack2 都是虚拟机所认识的的本地变量类型: java.lang.String,虚拟机并不认识 var, 所以 var 并不神奇。

OK,本次 Java 10 局部变量类型推断实战文章就到这里了,后续带来更多的 Java 10 的实战方面的文章。

往期干货推荐

1. 5月份值得一看的 Java 技术干货

2. 图解 https 单向认证和双向认证!

3. 最新后端架构师技术图谱!附学习资料~

4. 京东购物车的 Java 架构实现及原理

5. Java 中的伪共享详解及解决方案


Java技术栈 • 长按关注

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存