var:局部变量类型推断#
版本信息
- 最低 JDK:10(11 LTS GA)
- JEP:JEP 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());
}
}
- :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 是最温和的台阶——零运行时成本、纯减负,适合作为入门第一个新特性。