本篇主要介绍Java中的类与对象中 的static
成员
👩🏻🏫作者: 初入编程的菜鸟哒哒
📚系列文章目录:一、TvT——JavaSE(1)–Java的数据类型与变量
二、TvT——JavaSE(2)–Java的运算符
三、TvT——JavaSE(3)–Java的逻辑控制
四、TvT——JavaSE(4)–Java方法的使用
五、你真的学会了JavaSE中数组的定义与使用吗?
六、Java中的类与对象来袭
📜刷题笔记:
1️⃣TvT——C语言进阶の刷题【1】:指针进阶
前言
大家记得联系上一篇博客一起学习。
Java中的类与对象来袭(1)
static成员
1.static修饰成员变量
我们假想一种情况:你是学生,你的信息包括姓名年龄班级等,然后你们班级有很多学生,他们都有这些信息。
class Student {
public String name;
public double score;
public int age;
public String classes;
public Student (String name,double score,int age) {
this.name = name;
this.age = age;
this.score = score;
this.classes = classes;
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student("111",99,19,"2001");
Student student1 = new Student("222",89,16,"2001");
}
}
❓你们都是一个班的,如果这样写是不是就很冗余并且也很浪费空间呢?
那可不可以把班级单独拿出来?
这样每次new
对象就不用单独在堆上还给classes
建立一块空间了
那我们就可以把classes
存到方法区,使用static
修饰之后这个成员变量就不会存到对象里面,而会把它存到方法区里面(方法区中存放的是类型信息、常量、静态变量、即时编译器编译后的代码缓存、域信息、方法信息等。)里。
在方法区里面这个静态的成员变量只有一份。
使用static
修饰:
class Student {
public String name;
public double score;
public int age;
public static String classes = "2001";
public Student (String name,double score,int age) {
this.name = name;
this.age = age;
this.score = score;
}
}
这个时候classes
就是一个静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
但是访问静态成员变量也可以使用对象的引用访问:
public class Test {
public static void main(String[] args) {
Student student = new Student("111",99,19,"2001");
System.out.println(student.classes);
}
}
但是这样写严谨上来讲是不对的。
正确的方法应该是直接使用类名去访问它。
静态成员变量特性总结:
- 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
- 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
- 类变量存储在方法区当中
- 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)
如果你想直接使这个静态成员变量变成一个常量的话,可以直接在static
后面加一个final
:
public final static String classes = "2001";
2. static修饰成员方法
static
能定义静态成员变量也能定义静态成员方法:
class Student {
public String name;
public double score;
public int age;
public final static String classes = "2001";
public Student (String name,double score,int age) {
this.name = name;
this.age = age;
this.score = score;
}
public void upClass() {
System.out.println("普通方法");
}
public static void staticClass() {
System.out.println("静态方法");
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student("111",99,19);
Student student1 = new Student("222",89,16);
Student.staticClass();
}
}
直接类名.
就可以访问,不用创建对象:
可以不可以在静态方法里面访问普通成员变量呢?
报错了,所以答案是不可以的~
因为成员变量是依赖于对象的引用的,但是静态方法调用的时候是没有生成对象的,所以不可以调用。
如果你想访问的话可以自己new
一个对象,就像这样:
class Student {
public String name;
public double score;
public int age;
public static String classes = "2001";
public Student (String name,double score,int age) {
this.name = name;
this.age = age;
this.score = score;
}
public static void staticClass(Student is) {
is.name = "333";
System.out.println("静态方法");
}
}
public class Test {
public static void main(String[] args) {
Student student2 = new Student("123",99,18);
student2.staticClass(student2);
System.out.println(student2.name);
}
}
那普通成员方法可以调用静态成员变量吗?
看,没啥问题。
因为只要有Student
类,classes
就是一直存在的嘛,它谁都不依赖,所以谁都可以用它。
这也可以解释为什么我们创建函数public static void fun()
的时候要写这个static
了,因为main
函数是静态的(这个是JVM自己规定的),静态函数不能直接调用非静态函数。
如果fun
不是静态函数的话,调用就必须创建一个新对象,提供一个对象的引用,引用来调用fun
,否则不可以:
public class Test {
public void fun() {
;
}
public static void main(String[] args) {
Test test = new Test();
test.fun();
}
}
💌总结:
静态方法里面不能直接访问任何非静态成员变量,因为静态方法不依赖于对象,而成员变量是依赖于对象的,但是非静态的方法是可以直接访问静态方法的。
一个小拓展知识:
class Student {
public String name;
public double score;
public int age;
public static String classes = "2001";
public Student (String name,double score,int age) {
this.name = name;
this.age = age;
this.score = score;
}
public void goclass() {
System.out.println(this);
}
}
类里面的成员方法JVM会默认创建一个this
对象,在括号里隐藏了(是第一个参数),写出来应该是这样的:
public Student (Student this,String name,double score,int age) {
this.name = name;
this.age = age;
this.score = score;
}
public void goclass(Student this) {
System.out.println(this);
}
这也解释了为什么可以直接this.
3.static成员变量初始化
静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化。
- 就地初始化
就地初始化指的是:在定义时直接给出初始值,就像这样:
public static String classes = "2001";
- 静态代码块初始化(下一篇代码块的博客再详细讲)