Java static 新手入门指南:写给看不懂 static 的同学
作者:Sakura_youla
大家好,今天我们聊一个很多 Java 新手绕不开,但又特别容易整懵的关键字:static。
你别看它只是一个小单词,很多人刚学 Java 的时候,就是卡在这里:
- 明明方法就写在这个类里,为什么调不了?
- 两个对象改同一个变量,为什么数据互相影响?
- 有的代码还没进
main,怎么就先打印了? - 到底什么时候该加
static,什么时候不该加?
如果你也有这些困惑,今天这篇文章就是写给你的。
01 | 先说一个最扎心的报错
你大概率遇到过这种红红的报错:
public class Student {
private String name;
public void sayHi() {
System.out.println("Hi, " + name);
}
public static void main(String[] args) {
sayHi(); // 直接爆红
}
}
IDE 会提示你:
Non-static method ‘sayHi()’ cannot be referenced from a static context
很多同学看到这句话的第一反应是:
- 我方法就在这个类里啊,为什么不能调?
- 这不是同一个类吗?
- Java 是不是故意刁难我?
其实不是 Java 针对你,是你把 “类的东西” 和 “对象的东西” 搞混了。
02 | static 的本质,其实就一句话
如果只让你记住一句话,那就是:
static是属于类的,不是属于某一个对象的。
听起来还是有点抽象?
那我换一句更生活化的说法:
- 加了
static的东西,像是 班级公告栏,全班同学共用 - 没加
static的东西,像是 你自己的笔记本,只有你一个人用
Java 里很多困惑,其实都来自这里:
你到底是在操作“整个类共用的信息”,还是在操作“某一个对象自己的信息”?
03 | 为什么main里调用自己写的方法会报错?
这是大一同学最经典的坑之一。
你看这个代码,直觉上觉得能跑,但它就是报错:
public class Student {
public void sayHi() {
System.out.println("Hi");
}
public static void main(String[] args) {
sayHi(); // 报错
}
}
为什么会这样?
因为 main 是 static 的,它运行时 不依赖任何具体对象。
而 sayHi() 是普通方法,它要依赖某个对象才能运行。
换句话说:
编译器根本不知道你说的
sayHi(),到底是谁的sayHi()。
你方法写在 Student 类里没错,但它其实应该是:
- 小明的
sayHi() - 小红的
sayHi() - 还是小刚的 `sayHi()?
你没有说清楚。
所以编译器直接拒绝你:
你现在在
static环境里,连对象都没有,不能直接调对象的方法。
正确写法
public static void main(String[] args) {
Student s = new Student();
s.sayHi(); // 这样才行
}
先创建对象,再通过对象调用方法。
这样 Java 才知道你要调的是“这个对象的 sayHi()”。
04 | 多个对象操作同一个变量,数据为什么互不影响?
很多同学会问:
我创建了两个对象,然后修改其中一个的属性,为什么另一个对象没变?
比如这样:
public class Student {
String name;
public Student(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
Student a = new Student("小明");
Student b = new Student("小红");
a.name = "Java 小明";
System.out.println(a.name); // Java 小明
System.out.println(b.name); // 小红
}
}
为什么 b.name 没变?
因为 name 是 实例变量。
它没有加 static,所以它是每个对象自己私有的。
你可以这样理解:
a.name是小明自己的笔记本b.name是小红自己的笔记本
你在小明本子上写字,当然不会自动写到小红本子上。
所以这不是 bug,是本来就应该这样。
05 | 那什么时候会互相影响?
当变量是 static 的时候。
我们把代码改一下:
public class Student {
static String schoolName = "Java 大学";
String name;
public Student(String name) {
this.name = name;
}
public void show() {
System.out.println(name + " 来自 " + schoolName);
}
}
public class Main {
public static void main(String[] args) {
Student a = new Student("小明");
Student b = new Student("小红");
a.show();
b.show();
// 直接通过类名修改
Student.schoolName = "面向对象学院";
System.out.println("----- 修改后 -----");
a.show();
b.show();
}
}
输出:
小明 来自 Java 大学 小红 来自 Java 大学 ----- 修改后 ----- 小明 来自 面向对象学院 小红 来自 面向对象学院
你看,这次就出现“互相影响”了。
为什么?
因为 schoolName 是 static,它是所有对象共享的。
它不再是某个对象自己的属性,而是整个 Student 类公共的信息。
你改的是“公告栏”,那所有人看到的当然都会变。
06 | 怎么判断一个东西该不该加 static?
很多同学最怕的其实不是语法,而是不知道什么时候该用。
我给你一个特别好记的判断标准:
先问自己三个问题
第一,这个东西是不是只和“类本身”有关?
如果是,通常适合 static。
第二,这个东西是不是依赖“某个具体对象”才说得清?
如果是,不要 static。
第三,这个数据是不是“所有人共享”的?
如果是共享状态,就可以考虑 static。
常见判断举例
- 学校名、班级名、系统配置 → 通常适合
static - 学生姓名、成绩、年龄 → 不适合
static - 数学计算、工具方法 → 通常适合
static - 对象自己的行为,比如“自我介绍” → 不适合
static
一句话总结:
如果它是“类公共的”,就可能适合
static;如果它是“对象私有的”,就不要static。
07 | 为什么有的代码还没进 main 就先执行了?
有些同学第一次看到这种代码会很惊讶:
public class Demo {
static {
System.out.println("静态代码块先执行");
}
public static void main(String[] args) {
System.out.println("main 方法执行");
}
}
输出:
静态代码块先执行 main 方法执行
为什么 static {} 会先执行?
因为它叫 静态代码块。
它的作用是:在 类第一次被加载时 执行一次。
什么时候会触发类加载?
比如:
- 第一次运行这个类的
main - 第一次使用这个类的静态成员
- 第一次创建这个类的对象
所以顺序很好理解:
类先加载,然后才正式进入
main。
那静态代码块先跑,就很合理了。
这玩意一般拿来干嘛?
通常用于 类级别初始化,比如:
- 加载配置
- 初始化共享资源
- 打印一些类加载信息
入门阶段你先记住一点就够了:
static {}是类加载时执行的,不是创建对象时执行的。
08 | static常见的几个问题
Q1:static 方法能不能访问非 static 变量?
不能。
除非你先创建对象,再通过对象访问。
Q2:非 static 方法能不能访问 static 变量?
可以。
因为静态变量属于类,对象自然也能访问。
Q3:static 方法能不能用 this?
不能。
this 表示当前对象,而 static 方法不一定有对象,所以不让用。
Q4:static 方法能不能被重写?
不能真正重写。
子类可以写一个同名的 static 方法,但那叫 隐藏,不算多态里的重写。
09 | 最容易踩的几个坑
坑 1:觉得 static 方法不能调用任何方法
不是。
static 方法可以调用 其他 static 方法。
只是不能直接调用非 static 方法。
坑 2:把所有方法都习惯性加 static
这也不对。
如果方法明显依赖对象的数据,就不应该写成 static。
比如“学生自我介绍”,它依赖对象的姓名,就别加 static。
坑 3:看到 static 就想到“安静、静态、自动”
这些翻译其实容易误导人。
你只要记住一个意思就行:
static= 属于类。
10 | 结尾:先别怕,先把代码跑起来
最后我想说一句大实话:
很多新手学
static卡住,不是因为这个知识点太难,而是刚开始接触面向对象,脑子里还没建立“类 vs 对象”的概念。
所以不要急着背概念。
先从真实报错开始,先看代码现象,再反过头理解为什么。
你看懂一个报错,往往比背十个定义更有用。
如果你是大一同学,先记住下面这句话就够了:
static的东西属于类,普通的东西属于对象。
到此这篇关于Java static 新手入门指南:写给看不懂 static 的同学的文章就介绍到这了,更多相关Java static 关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
