跳转至

var:局部变量类型推断#

版本信息

  • 最低 JDK:10(11 LTS GA)
  • JEPJEP 286

为什么需要#

JDK 8 里局部变量常要写一长串类型名(Map<String,List<Integer>> map = new HashMap<>();),右侧已经写明了类型,左侧再写一遍是噪音。var 让编译器从右侧推断,减少样板、提升可读性。

语法#

package com.javamodern.var;

public class VarDemo {
    // 用 var 演示类型推断
    public static String buildGreeting() {
        var name = "Java";                   // (1)
        var version = 21;                    // 推断为 int
        var points = new int[]{1, 2, 3};     // 推断为 int[]
        return name + " " + version + " has " + points.length + " points";
    }

    public static void main(String[] args) {
        System.out.println(buildGreeting());
    }
}
  1. :material-lightbulb: var name = "Java" 被编译器推断为 String——var 只能用于局部变量且有初始化值,类型在编译期确定(运行时仍是强类型,不是 JS 的 var)。

与 JDK 8 旧写法对比#

String name = "Java";
int version = 21;
int[] points = new int[]{1, 2, 3};
var name = "Java";
var version = 21;
var points = new int[]{1, 2, 3};

底层原理#

var 纯属语法糖:编译器把 var x = expr; 还原为 T x = expr;T 取自 expr 的静态类型),字节码与显式写法完全一致,无运行时开销。

graph LR
    S["源码: var x = expr"] --> C["编译器推断 T = expr 的类型"]
    C --> B["字节码: T x = expr"]
    style S fill:#bbdefb

常见坑 / 最佳实践#

  • 只能用于局部变量,不能用于字段、方法参数、返回值。
  • 别让推断结果伤害可读性:var c = getConnection(); 看不出类型时,宁可显式写。
  • var 推断的是静态类型var x = Collections.emptyList(); 推断为 List<Object>,不是你以为的元素类型。

小结#

var 是最温和的台阶——零运行时成本、纯减负,适合作为入门第一个新特性。

参考#