Java是静态类型语言,变量声明必须明确类型且编译期确定;局部变量无默认值需显式初始化,成员变量有默认值;var仅限局部变量且不可推导null或泛型擦除类型;基本类型值拷贝,引用类型共享对象。
Java中声明变量必须明确类型,不能省略;没有var关键字(Java 10+虽引入var,但仅限局部变量且有严格限制)。
Java是静态类型语言,所有变量在编译期就必须确定类型。声明时要么直接初始化,要么确保在使用前被赋值,否则编译报错variable might not have been initialized。
int count; 合法声明,但不能直接用count参与计算,除非后续有赋值String name; 声明后值为null,调用name.length()会触发NullPointerException
final double PI = 3.14159; 声明即初始化,且不可再赋值类字段(成员变量)有默认初始值,方法内定义的局部变量没有——这是新手最常踩的坑。
public class Example{ private int number; // 成员变量 → 默认为 0 private String text; // 成员变量 → 默认为 null private boolean flag; // 成员变量 → 默认为 false public void method() { int localNum; // 局部变量 → 无默认值! // System.out.println(localNum); // 编译错误:variable localNum might not have been initialized localNum = 42; // 必须显式赋值后才能使用 } }
var 只适用于局部变量,且不能用于字段或返回值var不是类型推导万能钥匙,它只是语法糖,要求右侧表达式必须有明确、非泛型擦除后的类型,且不能是null。
var list = new ArrayList(); ✅ 推出ArrayList
var map = new HashMap(); ❌ 编译失败:类型不明确(擦除后无法推断泛型)var x = null; ❌ 编译失败:无法从null推导类型private var id = 123; ❌ 编译失败:var不能用于字段声明声明int、boolean等基本类型变量时,值直接存栈;而String、Object等引用类型变量,栈中只存指向堆内存对象的引用。
int a = 10; int b = a; → 修改b不影响a(值拷贝)StringBuilder sb1 = new StringBuilder("a"); StringBuilder sb2 = sb1; → sb2.append("b")会同时改变sb1.toString()结果(引用共享)String s1 = "hello"; String s2 = s1; → 表面看像共享,但s2 += " world"会创建新对象,s1不变(String不可变)真正容易被忽略的是:局部变量未初始化就使用、误把var当动态类型、以及对引用赋值后误以为是“复制对象”。这些不是语法问题,而是类型系统和JVM内存模型的刚性约束。