CodeGym /课程 /Java 语法 /static 变量和方法

static 变量和方法

Java 语法
第 6 级 , 课程 6
可用

“我们来谈一个新的主题。现在,我想讨论 static 变量和方法。”

“艾莉,我已经了解 static 变量和方法了。但我想了解更多详细信息。”

“当我们在类中声明变量时,我们会定义这些变量是只创建一次,还是该类的每个实例(对象)都将有自己的副本。默认情况下,将为每个对象创建变量的一个新副本。它看起来是这样的:”

类声明
class Cat                        // 类
{
    String name;                 // 变量

    Cat(String name)             // 构造方法
    {
        this.name = name;        // 变量初始化
    }
}
main 方法中的代码:
Cat cat1 = new Cat("奥斯卡"); // 创建一个 name 变量包含“奥斯卡”的对象
Cat cat2 = new Cat("米西"); // 创建一个 name 变量包含“米西”的对象
System.out.println(cat1.name);
System.out.println(cat2.name);
屏幕输出信息
奥斯卡
米西

“尽管是在同一个类 (Cat) 中声明的,变量 cat1.namecat2.name 却包含不同的值,因为它们引用不同的对象。”
“有道理。”
“但是,类的每个实例只能存在 static 变量的一个副本,并且必须使用类名访问该副本。”

类声明
class Cat                   // 类
{
    String name;            // 实例(非 static)变量
    static int catCount;    // static 变量

    Cat(String name)
    {
        this.name = name;
        Cat.catCount++;   // 将 static 变量加 1
    }
}
main 方法中的代码:
System.out.println(Cat.catCount);
Cat cat1 = new Cat("奥斯卡");

System.out.println(Cat.catCount);
Cat cat2 = new Cat("米西");

System.out.println(cat1.name);
System.out.println(cat2.name);
System.out.println(Cat.catCount);
屏幕输出:
 0
1
奥斯卡
米西
2

“嗯,也很有道理。”

“Java 方法分为两个类别。实例方法是在对象上调用的,并且可以访问该对象的数据。static 方法没有该访问权限,因为它们根本没有对象引用。但是,它们可以引用类的 static 变量和其他 static 方法。

static 方法无法处理非 static 方法或非 static 变量!”

“为什么呢,艾莉?”

“每个实例变量都包含在一个对象中。只有当你具有对该对象的引用时,才可以访问它。static 方法没有此类引用。”

“实例方法有这种引用吗?”

“是的,它被间接传递给实例方法。对调用实例方法的对象的引用被间接传递给该实例方法。存储此引用的变量称为 this。this 使得方法始终可以访问对象的数据或调用同一对象上的另一个非 static 方法。

将 null(而不是对象引用)传递给 static 方法。这就是它们不能处理非 static 变量和方法的原因。它们根本没有对与这些变量和方法相关联的对象的引用。”

“好的,艾莉,我明白了。”

“以下是非 static 方法的工作原理:

代码看起来如下所示
Cat cat = new Cat();
String name = cat.getName();
cat.setAge(17);
cat.setChildren(cat1, cat2, cat3);
实际发生的情况如下
Cat cat = new Cat();
String name = Cat.getName(cat);
Cat.setAge(cat, 17);
Cat.setChildren(cat, cat1, cat2, cat3);
使用 <对象>.<方法名称> 调用方法时,实际上是在调用类方法,并将该对象作为第一个参数进行传递。在方法内,对象称为‘this’。方法中的所有操作都是针对此对象及其数据执行的。”

“下面是 static 方法的工作原理:

代码看起来如下所示
Cat cat1 = new Cat();
Cat cat2 = new Cat();
int catCount = Cat.getAllCatsCount();
实际发生的情况如下
Cat cat1 = new Cat();
Cat cat2 = new Cat();
int catCount = Cat.getAllCatsCount(null);
当调用 static 方法时,没有对象被传递给它。也就是说,‘this’ 相当于空值 null。这导致 static 方法无法访问非 static 变量和方法,因为它没有任何内容隐式传递给非 static 方法。”

“如果变量或方法前面有关键字 static,则为 static。”

“既然限制如此严格,为什么需要这种方法呢?”

“嗯,这种方法自有其优点。”

“首先,我们不必传递对象引用即可使用 static 方法和变量。

“第二,有时需要只有一个变量副本。例如,System.out(System 类的 static out 变量)。”

“第三,有时你需要先调用一个方法,然后才能创建对象。”

“艾莉,可以给我举个这样的例子吗?”

“你为什么认为 main() 方法是 static?它是 static,因此程序员可以在任意对象创建之前,在将类加载到内存后立即调用它。

评论 (28)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
烂泥扶不上墙机器人 级别 9,Chongqing,China
20 二月 2024
来自GPT的回答 static 变量和方法 是属于类的变量和方法,而不是属于类的实例对象的变量和方法。当一个类被加载到内存中时,static 变量和方法会被分配内存空间,且只会被分配一次。 static 变量: static 变量也称为类变量,它被所有类的实例对象所共享。可以通过类名直接访问 static 变量,而不需要创建类的实例对象。static 变量通常用来表示类级别的常量或者共享的状态信息。 示例: public class MyClass { public static int count = 0; public MyClass() { count++; } } 在上面的示例中,count 是一个 static 变量,表示 MyClass 类的实例对象的数量。 static 方法: static 方法也称为类方法,它不依赖于类的实例对象,可以直接通过类名调用。static 方法通常用来执行与类相关的操作,而不是与类的实例对象相关的操作。 示例: public class MathUtils { public static int add(int a, int b) { return a + b; } } 在上面的示例中,add 是一个 static 方法,可以直接通过类名 MathUtils.add(1, 2) 来调用。 需要注意的是,static 方法内部不能直接访问非静态变量或方法,因为非静态变量和方法是属于实例对象的。 总结: static 变量和方法属于类,不依赖于类的实例对象。 static 变量被所有类的实例对象所共享。 static 方法可以直接通过类名调用,不需要创建类的实例对象。 static 方法内部不能直接访问非静态变量或方法。
职业混分师 级别 31,China,China
25 七月 2023
调用 static 方法时,不会向它传递任何对象。换言之,‘this’等于 null。这就是 static 方法无法访问非 static 变量和方法的原因(因为它没有任何内容明确地传递给非 static 方法)。 这句话的翻译不是人工翻译的吧?为什么好多课程的文字解释都这么拗口?并且不易理解?
sky 级别 22
12 八月 2022
这就是 static 方法无法访问非 static 变量和方法的原因(因为它没有任何内容明确地传递给非 static 方法)。 有人可以理解?
Super Ego 级别 14,Wu Han,China
30 一月 2023
因为它是依托类而存在的, 不会把对象自身作为参数传递的意思吧
KAI 级别 22,Wenzhou,China
8 三月 2023
类变量和类方法是随着类加载而加载一次,使用类方法可以通过类名.类方法名访问,无需创建对象访问。也就是说使用类方法不需要传递对象引用,this=null,类方法里就没有对象引用,没有对象引用就无法访问实例变量和实例方法。但反过来,实例方法可以访问static和非static(个人理解 如有不对 欢迎指正)
Ocean 级别 22,China,Hong Kong
25 七月 2022
有点绕口
自证预言 级别 41,Пекин,China
30 五月 2022
main方法是static方法,这样是不是JVM调用的时候就不需要创建对象,直接调用了
shoudlee 级别 9,China,China
2 五月 2022
It works just like

self
in Python.
诸葛靓 级别 2,China,China
8 五月 2021
调用 static 方法时,不会向它传递任何对象。换言之,‘this’等于 null。这就是 static 方法无法访问非 static 变量和方法的原因(因为它没有任何内容明确地传递给非 static 方法)。 这句话翻译的是不是有点问题
小K185 级别 7
9 四月 2021
?
海风吹牛逼 级别 12,Hong Kong
5 四月 2021
这中文是机翻吗?让我看的有点头疼!!
John Squirrels 级别 41,San Francisco,Poland
6 四月 2021
Could you please specify, where exactly you have noticed the transtlation not suitable for you.
Faker 级别 10,Guangzhou,China
12 四月 2021
It would be even better if you could bring in an in-memory image
lizhi 级别 20,英国
14 三月 2021
I can not understand the third one of static's advantages,who can talk about it?
Ywuuu 级别 8,San Diego
27 一月 2022
紧接着后面有讲啊: main()方法就是static,先有main,才有main中的对象创建