Java 变量与常量
变量是程序的"基本存储单元"——给它起个名字,把数据存进去,以后用名字就能取出数据。Java 是强类型语言,每个变量使用前必须先声明类型,这是它和 Python/JS 最大的不同。本章带你彻底搞懂 Java 变量。
1. 变量声明:类型 + 名字 + 值
Java 变量声明的格式是 类型 变量名 = 值;,三种方式:
public class VarDemo {
public static void main(String[] args) {
// 1. 先声明,后赋值
int a;
a = 10;
// 2. 声明并赋值(最常用)
int b = 20;
// 3. 同时声明多个同类型变量
int c = 1, d = 2, e = 3;
System.out.println(a + " " + b + " " + c + " " + d + " " + e);
// 输出: 10 20 1 2 3
}
}注意 = 是赋值,不是"等于"。等号左边是变量名,右边是要存的值。
2. var 自动推断(Java 10+)
从 Java 10 开始,可以用 var 关键字代替类型,编译器会根据右边的值自动推断类型:
public class VarInfer {
public static void main(String[] args) {
// Java 10+ 引入 var,编译器自动推断类型
var name = "小明"; // 推断为 String
var age = 20; // 推断为 int
var pi = 3.14; // 推断为 double
var numbers = new int[]{1, 2, 3}; // 推断为 int[]
System.out.println(name + " " + age + " " + pi);
// ⚠️ var 只能用于局部变量(方法内),不能用于成员变量
// ⚠️ 必须在声明时赋值,否则编译器无法推断
// var x; // ❌ 编译报错
}
}var 是语法糖——编译期就确定了真实类型,运行时和直接写类型完全一样,不影响性能。它适合类型很明显的场合(如 var list = new ArrayList<String>()),如果类型复杂或可读性差,还是老老实实写显式类型。
3. 三种变量的作用域
Java 把变量按声明位置分三种,作用域和生命周期各不相同:
- 局部变量(Local Variable):方法内部声明,只在方法执行期间存在,方法结束就被回收。必须手动初始化才能使用。
- 成员变量(Instance Variable):类内部、方法外部声明,属于对象。每个对象有一份独立的拷贝。有默认值(int 默认 0、引用类型默认 null)。
- 静态变量(Class Variable):用
static修饰,属于类本身,所有对象共享一份。程序启动时分配,结束时回收。
public class ScopeDemo {
// 1. 静态变量(类变量):属于类,所有对象共享
static int counter = 0;
// 2. 成员变量(实例变量):属于对象,每个对象一份
String name;
public ScopeDemo(String name) {
this.name = name;
counter++; // 每创建一个对象,计数器 +1
}
public static void main(String[] args) {
// 3. 局部变量:方法内,只在方法执行期间存在
int localX = 100;
if (localX > 50) {
// 4. 块级作用域:只在 if 块内有效
int blockY = 200;
System.out.println(blockY); // 200
}
// System.out.println(blockY); // ❌ 编译报错:blockY 在块外不可见
new ScopeDemo("小明");
new ScopeDemo("小红");
System.out.println("共创建 " + counter + " 个对象");
// 输出: 共创建 2 个对象
}
}4. final 常量
用 final 修饰的变量只能赋值一次,赋值后不能再改——这就是"常量",相当于其他语言的 const。
public class FinalDemo {
// 静态常量:全大写 + 下划线
static final double PI = 3.14159;
static final int MAX_SIZE = 100;
public static void main(String[] args) {
// 局部常量
final String NAME = "小明";
// NAME = "小红"; // ❌ 编译报错:final 变量不能重新赋值
// 引用类型 + final:引用不可变,但对象内部可以变
final int[] arr = {1, 2, 3};
arr[0] = 99; // ✅ 可以修改元素
System.out.println(arr[0]); // 99
// arr = new int[]{4, 5}; // ❌ 编译报错:不能重新指向新数组
}
}几个易错点:
- 静态常量命名约定是全大写 + 下划线(
MAX_SIZE、PI)。 final修饰引用类型时,引用本身不可变(不能再指向新对象),但对象内部内容可以修改(数组可以改元素,List 可以 add)。这是新手最常踩的坑。- 局部变量、方法参数、成员变量、静态变量都可以加
final。
5. 成员变量的默认值
成员变量(实例变量、静态变量)声明后即使不赋值也有默认值,而局部变量没有默认值,必须先初始化才能使用——这是 Java 编译器的安全检查:
public class DefaultValue {
// 成员变量有默认值(不强制初始化)
int intField; // 默认 0
boolean boolField; // 默认 false
double doubleField; // 默认 0.0
char charField; // 默认 '\u0000'(空字符)
String strField; // 默认 null(引用类型都是 null)
public static void main(String[] args) {
DefaultValue d = new DefaultValue();
System.out.println(d.intField); // 0
System.out.println(d.boolField); // false
System.out.println(d.doubleField); // 0.0
System.out.println(d.strField); // null
// ⚠️ 局部变量没有默认值,必须先初始化才能用
// int x;
// System.out.println(x); // ❌ 编译报错:可能尚未初始化变量 x
}
}6. 变量命名小贴士
- 使用驼峰命名:
userName、totalCount,不要user_name(那是 C/Python 风格)。 - 名字要有意义:
int age = 20;远好于int a = 20;。 - 布尔变量用
is/has前缀更清晰:boolean isReady、boolean hasPermission。 - 避免单字母变量(循环计数器
i、j、k除外)。
小结
这一章你掌握了 Java 变量的全部要点:声明方式、var 推断、三种作用域、final 常量、默认值规则。下一篇我们看 Java 的数据类型——基本类型有哪些?引用类型和基本类型有什么区别?类型怎么转换?
← 上一篇 Java 基础语法
下一篇 Java 数据类型 →