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

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

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

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

什么是局部变量类型推断

var javastack = "javastack";
System.out.println(javastack);

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

var javastack = "javastack";

就等于:

String javastack = "javastack";

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

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

1、字面量定义局部变量

private static void testVar() {
    var javastack = "javastack";
    System.out.println(javastack);
}

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

private static void testMethod() {
    var javastack = getJavastack();
    System.out.println(javastack);
}

public static String getJavastack() {
    return "javastack";
}

3、循环中定义局部变量

private static void testLoop() {
    for (var i = 0; i < 3; i++) {
        for (var m = 10; m < 15; m++) {
            System.out.println(i + m);
        }
    }
}

4、泛型结合局部变量

private static void testGeneric() {
    // 表达式1
    List<String> list1 = new ArrayList<>();
    list1.add("javastack");

    // 表达式2
    var list2 = new ArrayList<>();
    list2.add(2018);

    // 表达式3
    var list3 = new ArrayList<String>();
    list3.add("javastack");
}

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

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

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

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

1、类成员变量类型

// 编译报错
private var javastack = "Java技术栈";

2、方法返回类型

/**
 * 编译报错
 * @return
 */
public static var getJavastack(){
     return "Java技术栈";
}

3、Lambda 表达式

private static void testLambda() {
    Runnable runnable = () -> System.out.println("javastack");

    // 编译报错
    // var runnable = () -> System.out.println("javastack");
}

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

局部变量类型推断优缺点

优点:简化代码

CopyOnWriteArrayList list1 = new CopyOnWriteArrayList();
ConcurrentModificationException cme1 = new ConcurrentModificationException();
DefaultServiceUnavailableRetryStrategy strategy1 = new
        DefaultServiceUnavailableRetryStrategy();

var list2 = new CopyOnWriteArrayList<>();
var cme2 = new ConcurrentModificationException();
var strategy2 = new DefaultServiceUnavailableRetryStrategy();

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

缺点:掩盖类型

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

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

var关键字原理

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

private static void testByteCode() {
    String javastack1 = "javastack";
    var javastack2 = "javastack";
}

编译成字节码后:

private static testByteCode()V
L0
LINENUMBER 22 L0
LDC "javastack"
ASTORE 0
L1
LINENUMBER 23 L1
LDC "javastack"
ASTORE 1
L2
LINENUMBER 24 L2
RETURN
L3
LOCALVARIABLE javastack1 Ljava/lang/String; L1 L3 0
LOCALVARIABLE javastack2 Ljava/lang/String; L2 L3 1
MAXSTACK = 1
MAXLOCALS = 2

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

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

往期干货推荐

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

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

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

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

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

原文发布于微信公众号 - Java技术栈(javastack)

原文发表时间:2018-06-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏架构师小秘圈

深入理解Java的接口和抽象类

架构技术干货第一时间送达! 对于面向对象编程来说,抽象是它的一大特征之一。在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。这两者有太多相似的地方...

34550
来自专栏从流域到海域

《笨办法学Python》 第28课手记

《本办法学Python》 第28课手记 本节课为布尔表达式的练习课。 作者在本课给出了将复杂的表达式逐级降解为一个单一结果,请记住那个流程。 本节课我将不会给出...

19470
来自专栏java一日一条

Java有值类型吗?

有人看了我之前的文章『Swift 语言的设计错误』,问我:“你说 Java 只有引用类型(reference type),但是根据 Java 的官方文档,Jav...

14120
来自专栏Java3y

插入排序就这么简单

插入排序就这么简单 从上面已经讲解了冒泡和选择排序了,本章主要讲解的是插入排序,希望大家看完能够理解并手写出插入排序的代码,然后就通过面试了!如果我写得有错误的...

49780
来自专栏带你撸出一手好代码

Java元组的使用

元组在计算机领域有着特殊的意义,这个名字听起来似乎有些陌生, 平时在写代码也基本没什么应用场景, 然而, 出人意料的是, 元组跟程序设计密切相关, 可能有的同学...

53680
来自专栏苦逼的码农

从0打卡leetcode之day8--反转整数

假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。根据这个假设,如果反转后的整数溢出,则返回 0。

14940
来自专栏noteless

[五]java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用

java8 流相关的操作中,我们把它理解 "累加器",之所以加引号是因为他并不仅仅是加法

34030
来自专栏Python小屋

Python标准库collections中与字典有关的类

Python标准库中提供了很多扩展功能,大幅度提高了开发效率。这里主要介绍OrderedDict类、defaultdict类和Counter类。 (1)Orde...

29860
来自专栏MyBlog

Effective.Java 读书笔记(11)关于clone方法

说到clone方法,我们来提一提Cloneable这个接口,这个接口是用来作为一种标记某对象允许被clone的一种混合接口,可是不幸运的是,这个接口并没能起到该...

11720
来自专栏Java帮帮-微信公众号-技术文章全总结

细说反射,Java 和 Android 开发者必须跨越的坎【面试+工作】

我来翻译一下:反射技术通常被用来检测和改变应用程序在 Java 虚拟机中的行为表现。它是一个相对而言比较高级的技术,通常它应用的前提是开发者本身对于 Java ...

19540

扫码关注云+社区

领取腾讯云代金券