当前位置: 首页 > news >正文

static

目录

static 修饰成员变量

static 修饰成员方法

static 成员变量初始化

就地初始化

静态代码块初始化


static 是 静态 的意思,可以用来修饰成员变量成员方法

我们通过一个例子来看:

public class Student {private int id;private String name;private int age;public Student() {}public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}
}

我们使用上述学生类实例化对象

    public static void main(String[] args) {Student s1 = new Student(1, "张三", 18);Student s2 = new Student(2, "李四", 19);Student s3 = new Student(3, "王五", 19);}

每个对象都有自己特有的 id、姓名 和 年龄 信息,这些信息是对不同学生进行描述的

 

上述 id、姓名 以及 年龄 是在 Student 类中定义的成员变量每个对象都会包含一份,使用这些信息来描述具体的学生

而现在需要添加一个 classRoom 来描述学生的班级(假设所有学生的班级都是相同的)

而 classRoom 对于所有学生都是相同的,因此,没有必要每个学生对象中都存储一份,可以将其提取出来,让所有学生共享

在 Java 中,被 static  修饰的成员称为静态成员,也可以称为类成员,不属于某个具体的对象,而是所有对象所共享

static 修饰成员变量

static 修饰的成员变量,称为静态成员变量

静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的

静态成员变量可以直接通过 类名 访问 

public class Student {private int id;private String name;private int age;private static String classRoom = "一班";public Student() {}public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}public static void main(String[] args) {System.out.println(Student.classRoom);}
}

也可以通过对象访问

public class Student {private int id;private String name;private int age;private static String classRoom = "一班";public Student() {}public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}public static void main(String[] args) {Student s1 = new Student(1, "张三", 18);Student s2 = new Student(2, "李四", 19);Student s3 = new Student(3, "王五", 19);System.out.println(s1.classRoom);System.out.println(s2.classRoom);System.out.println(s3.classRoom);}
}

classRoom 是对象所共享的,因此获取到的 classRoom 是相同的

若进行调试,也可以看到,静态成员变量并没有存储到某个具体的对象中 

静态成员变量是所有对象共享的,是类的属性,因此,在 JVM 进行类加载时就会为其开辟空间进行存储(存储在方法区中),它的生命周期伴随类的一生(随类的加载而创建,随类的卸载而销毁

总结一下静态成员变量的特性

(1)不属于某个具体的对象,是类的属性,是所有对象共享的,不存储在某个对象的空间中

(2)可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问

(3)存储在方法区中,其生命周期伴随类的一生

 

static 修饰成员方法

一般类中的数据成员都设置为 private,成员方法设置为 public,上述我们直接在 Student 类中进行访问,那 Student 类中的 classRoom 属性如何在类外进行访问呢?

在 Java 中,被 static 修饰的成员方法是类的方法,不是某个对象所特有的,因此,静态成员一般是通过静态方法来访问的

public class Student {private int id;private String name;private int age;private static String classRoom = "一班";public Student() {}public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}public static String getClassRoom() {return classRoom;}
}

可以直接通过类名调用

public class Test {public static void main(String[] args) {System.out.println(Student.getClassRoom());}
}

也可以通过对象调用

public class Test {public static void main(String[] args) {Student student = new Student();System.out.println(student.getClassRoom());}
}

更推荐使用 类名 调用的方式

不能在静态方法中访问任何非静态成员变量


 

静态方法中也不能调用任何非静态方法

 

为什么在静态方法中不能访问任何非静态成员,也不能调用任何非静态方法?

(1)静态方法 与 非静态成员变量和方法 的作用域不同 

静态方法 属于类本身的,是类方法,而不是特定对象的方法,这也就意味着 静态方法可以在不创建实例的情况下被调用

非静态成员变量 和 非静态成员方法 是与创建的对象相关联的,每个对象都有自己的副本,这些变量和方法只能通过对象实例来访问

(2)静态方法中没有 this 引用

静态方法中不具有隐含的 this 引用,这是因为它无法知道自己在哪个对象上下文中被调用

而非静态成员变量和方法依赖于 this 来引用当前对象的状态

因此,在静态方法中调用时无法传递 this 引用,没有对象的上下文可引用,导致编译器无法识别哪些非静态成员应该被访问

(3)作用不同

静态方法通常用于执行与类相关的操作

而非静态成员变量和方法用于表示对象的状态的行为

将静态方法和非静态成员变量和方法区分开,有利于保持代码的清晰性和可维护性

在构造方法中可以访问和使用静态成员变量,也可以调用静态成员方法

public class Student {private int id;private String name;private int age;private static String classRoom = "一班";public Student() {System.out.println(getClassRoom());classRoom = "二班";System.out.println(getClassRoom());}public static String getClassRoom() {return classRoom;}
}

 

静态方法无法重写,不能用来实现多态

public class Person {public static void method() {System.out.println("Person method...");}
}

 

子类中也可以存在 method 方法,但是不会构成重写

public class Student extends Person{private int id;public static void method() {System.out.println("Student method...");}
}

访问 method 方法:

public class Test {public static void main(String[] args) {Person person = new Student();person.method();}
}

运行结果:

 

可以看到 person 调用的是父类静态方法,而不是子类的静态方法

 

为什么呢?

(1)静态方法是在编译时期进行绑定的,而不是在运行时,这也就意味着当调用一个静态方法时,编译器会根据 引用类型 确定要调用的方法,而不是类的实际类型

(2)静态方法是属于类的方法,而不是实例的,因此,它们不能被子类重写重写是基于实例的方法,需要通过对象来调用

(3)重写涉及到多态性,在实例方法中,它们可以根据对象的实际类型来确定调用哪个方法,而静态方法不具备这种特性

总结一下静态成员方法的特性: 

(1)不属于某个具体的对象,是类方法

(2)可以通过对象调用,也可以通过类名调用,更推荐使用类名调用

(3)不能在静态成员方法中访问任何非静态成员变量

(4)静态成员方法中不能调用任何非静态成员方法

(5)可以在构造方法中使用静态成员变量,也可以调用静态成员方法,但是不推荐

(6)静态方法无法重写,不能用来实现多态

 

static 成员变量初始化

虽然静态成员变量可以在构造方法中初始化,但是一般不会将其放在构造方法中初始化,构造方法中初始化的是对象相关的实例属性

静态成员变量一般通过两种方式进行初始化:

就地初始化

静态代码块初始化

 

就地初始化

就地初始化:在定义时直接给出初始值

private static String classRoom = "一班";

 

静态代码块初始化

静态代码块:使用 static 定义的代码块

private static String classRoom;
static {
        classRoom = "一班";
}


http://www.mrgr.cn/news/49787.html

相关文章:

  • 叉车超速熄火器 三级速度预警 促进厂区物流作业规范化管理
  • 商品详情 API 接口的调用次数是否有限制?
  • 【笔记】vue课堂小作业之书购物车列表的增删改查小记
  • HTML5实现古典音乐网站源码模板2
  • 数据结构实验十一 图的创建与存储
  • 电脑如何屏蔽网站?使用浏览器或者 Hosts 文件都可以
  • YOLO11改进|注意力机制篇|引入CoT注意力机制
  • 【多线程奇妙屋】“线程等待” 专讲,可不要只会 join 来线程等待哦, 建议收藏 ~~~
  • Linux下Git操作
  • pycharm - terminal打开没自动进入虚拟环境
  • DS线性表之栈的讲解和实现(4)
  • 基于微信小程序的四六级词汇springboot+论文开题报告源码调试讲解
  • 指令:计算机的语言(二)
  • 48 | 代理模式:代理在RPC、缓存、监控等场景中的应用
  • 五大检索模式,精确定位所需专利
  • 程序发生闪退且没有生成dump文件问题的排查经验总结与分享
  • springboot 修复 Spring Framework 特定条件下目录遍历漏洞(CVE-2024-38816)
  • AI学习指南深度学习篇-迁移学习(Transfer Learning)简介
  • 母鸡----------
  • 行星滚柱丝杠的特点