发布于2026-07-29 阅读(0)
扫一扫,手机访问
你大概率遇到过这种红红的报错:
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
很多同学看到这句话的第一反应是:
其实不是 Ja va 针对你,是你把 “类的东西” 和 “对象的东西” 搞混了。
如果只让你记住一句话,那就是:
static是属于类的,不是属于某一个对象的。
听起来还是有点抽象?
换一句更生活化的说法:
static 的东西,像是 班级公告栏,全班同学共用static 的东西,像是 你自己的笔记本,只有你一个人用Ja va 里很多困惑,其实都来自这里:
你到底是在操作“整个类共用的信息”,还是在操作“某一个对象自己的信息”?
这是大一同学最经典的坑之一。
你看这个代码,直觉上觉得能跑,但它就是报错:
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(); // 这样才行
}
先创建对象,再通过对象调用方法。
这样 Ja va 才知道你要调的是“这个对象的 sayHi()”。
很多同学会问:
我创建了两个对象,然后修改其中一个的属性,为什么另一个对象没变?
比如这样:
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 = "Ja va 小明";
System.out.println(a.name); // Ja va 小明
System.out.println(b.name); // 小红
}
}
为什么 b.name 没变?
因为 name 是 实例变量。
它没有加 static,所以它是每个对象自己私有的。
你可以这样理解:
a.name 是小明自己的笔记本b.name 是小红自己的笔记本你在小明本子上写字,当然不会自动写到小红本子上。
所以这不是 bug,是本来就应该这样。
当变量是 static 的时候。
我们把代码改一下:
public class Student {
static String schoolName = "Ja va 大学";
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();
}
}
输出:
小明 来自 Ja va 大学 小红 来自 Ja va 大学 ----- 修改后 ----- 小明 来自 面向对象学院 小红 来自 面向对象学院
你看,这次就出现“互相影响”了。
为什么?
因为 schoolName 是 static,它是所有对象共享的。
它不再是某个对象自己的属性,而是整个 Student 类公共的信息。
你改的是“公告栏”,那所有人看到的当然都会变。
很多同学最怕的其实不是语法,而是不知道什么时候该用。
给你一个特别好记的判断标准:
第一,这个东西是不是只和“类本身”有关?
如果是,通常适合 static。
第二,这个东西是不是依赖“某个具体对象”才说得清?
如果是,不要 static。
第三,这个数据是不是“所有人共享”的?
如果是共享状态,就可以考虑 static。
staticstaticstaticstatic一句话总结:
如果它是“类公共的”,就可能适合
static;如果它是“对象私有的”,就不要static。
有些同学第一次看到这种代码会很惊讶:
public class Demo {
static {
System.out.println("静态代码块先执行");
}
public static void main(String[] args) {
System.out.println("main 方法执行");
}
}
输出:
静态代码块先执行 main 方法执行
为什么 static {} 会先执行?
因为它叫 静态代码块。
它的作用是:在 类第一次被加载时 执行一次。
比如:
main所以顺序很好理解:
类先加载,然后才正式进入
main。
那静态代码块先跑,就很合理了。
通常用于 类级别初始化,比如:
入门阶段你先记住一点就够了:
static {}是类加载时执行的,不是创建对象时执行的。
不能。
除非你先创建对象,再通过对象访问。
可以。
因为静态变量属于类,对象自然也能访问。
不能。
this 表示当前对象,而 static 方法不一定有对象,所以不让用。
不能真正重写。
子类可以写一个同名的 static 方法,但那叫 隐藏,不算多态里的重写。
不是。
static 方法可以调用 其他 static 方法。
只是不能直接调用非 static 方法。
这也不对。
如果方法明显依赖对象的数据,就不应该写成 static。
比如“学生自我介绍”,它依赖对象的姓名,就别加 static。
这些翻译其实容易误导人。
你只要记住一个意思就行:
static= 属于类。
最后说一句大实话:
很多新手学
static卡住,不是因为这个知识点太难,而是刚开始接触面向对象,脑子里还没建立“类 vs 对象”的概念。
所以不要急着背概念。
先从真实报错开始,先看代码现象,再反过头理解为什么。
你看懂一个报错,往往比背十个定义更有用。
如果你是大一同学,先记住下面这句话就够了:
static的东西属于类,普通的东西属于对象。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8