【Java SE】深入理解static关键字

🥰🥰🥰来都来了,不妨点个关注叭!
👉博客主页:欢迎各位大佬!👈

在这里插入图片描述

文章目录

  • 1.static关键字
    • 1.1 static的概念
    • 1.2 static的作用
    • 1.3 static的用法
      • 1.3.1 static修饰成员变量
      • 1.3.2 static修饰成员方法
      • 1.3.3 static修饰成员变量初始化
  • 2. 代码块
    • 2.1 普通代码块
    • 2.2 构造代码块(实例代码块、非静态代码块)
    • 2.3 静态代码块
    • 2.4 同步代码块
  • 3. 内部类
    • 3.1 实例内部类
    • 3.2 静态内部类
    • 3.3 局部内部类
    • 3.4 匿名内部类

1.static关键字

1.1 static的概念

【概念】:static表示"全局"/"静态"的含义,但是Java语言中没有全局变量的概念,因此在Java中用static来修饰方法/变量等,称为静态成员方法/静态成员变量,也可以形成静态static代码块。
【特点】
被static修饰的成员变量/成员方法不依赖该类的任何对象,即它不依赖类特定的实例,被类的所有实例共享,静态的成员不属于对象,通过类名进行访问
【为什么】
因为只要这个类被加载,Java虚拟机可以根据类名在运行时数据区的方法区内找到它们,因此,可以在它的任何对象创建之前访问,无需引用任何对象。
【注意】
1)非静态成员变量/方法从属于对象
2)静态成员变量/方法从属于类

1.2 static的作用

现在有Student类,实例化六个对象,分别为student1 、student2、student3、student4 、student5和student6,每个对象都有自己特有的学号、性别、成绩、姓名等信息,代码如下:

public class Student {
    private int sno;//学号
    public String sex;//性别
    public int score;//分数
    public String name;//姓名

     public Student(int sno, String sex, int score, String name) {
        this.sno = sno;
        this.sex = sex;
        this.score = score;
        this.name = name;
    }
}

class Test {
    public static void main(String[] args) {
        Student student1  = new Student(1,"女",98,"张三");
        Student student2  = new Student(2,"男",90,"李四");
        Student student3  = new Student(3,"男",88,"小丁");
        Student student4  = new Student(4,"女",99,"小万");
        Student student5  = new Student(5,"女",80,"小晚");
        Student student6  = new Student(6,"男",77,"小新");
    }
}

在这里插入图片描述
假设这六名同学为同一个班的, 故他们也在同一间教室上课,如何表示?
如果在Student类中再加一个成员变量classRoom,用来保存教室,这样的方案是否可行?
在回答这些问题之前,我们先来想一想,如果这样做的话,每一个对象都会包含classRoom这一份实例变量,用这些信息来具体描述每一个学生。但是我们清楚地知道,并不需要每实例化一个对象,都保存着这个教室成员变量classRoom,这六个对象都在这个教室,需要他们来共享这个变量。在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,并不属于某个具体的对象,是所有对象所共享的。
简而言之:在不用创建对象的情况下,调用类的方法/变量,是可以共享的

1.3 static的用法

1.3.1 static修饰成员变量

在Java中,static修饰的成员变量,称为静态成员变量
【静态成员变量特性】
1)不属于某个具体的对象,是类的属性,所有对象共享,不存储在某个对象的空间中,类变量存储在方法区当中
2)可以通过类名访问,也可以通过对象访问,一般更推荐使用类名访问(毕竟都使用static啦,那就使用其特有的属性)
3)生命周期伴随类的一生,即随类的加载而创建,随类的卸载而销毁
上述问题的解决代码:

public class Student {
    private int sno;//学号
    public String sex;//性别
    public int score;//分数
    public String name;//姓名
    
    public static String classRoom = "L1210";
}

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

打印结果如下:
在这里插入图片描述
可以清楚看到,静态成员变量并未存储到某一个对象中,存在方法区当中,供所有对象共享
在这里插入图片描述

1.3.2 static修饰成员方法

在Java中,被static修饰的成员方法称为静态成员方法/类方法
【静态成员方法特性】
1)不属于某个具体的对象,是类方法
2)可以通过类名访问,也可以通过对象访问,一般更推荐使用类名访问
3)对于非静态成员变量,不能在静态方法中访问任何非静态成员变量
举个例子:test1为非静态方法,age为静态变量,test1无法访问age变量

public void test1() {
static int age = 12;
}

在这里插入图片描述

4)对于非静态方法,静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用,即通俗记忆静态不能访问非静态,但是静态的方法内部可以访问非静态数据等,但不是能够直接使用非静态,必须依赖对象。所以这也是为什么main方法是static修饰的,既可以访问静态成员变量调用静态成员方法,也可以访问非静态成员变量调用非静态成员方法
举个例子:test2不是静态方法,test1是静态方法,所以test1不能调用test2这个非静态方法

class Test {
    public static void main(String[] args) {
        test2();
    }

    public static void test1() {
        System.out.println("!!!");
    }

    public void test2() {
        test1();
    }

在这里插入图片描述
4)静态方法无法重写,不能用来实现多态
总结
1)非静态成员方法不能访问静态成员变量和调用静态成员方法
2)静态成员方法可以访问非静态成员变量和调用静态成员方法,但不是直接的,依赖于对象

1.3.3 static修饰成员变量初始化

1)直接初始化
在定义时直接给出初始值(如下面这段代码classRoom是静态成员变量,在定义时候直接初始化)

public static String classRoom = "L1210";

2)默认初始化
3)通过get和set方法进行初始化

public class Student {
    private int sno;//学号
    public String sex;//性别
    public int score;//分数
    public String name;//姓名
    public static String classRoom ;
    
    public static String getClassRoom() {
        return classRoom;
    }
    
    public static void setClassRoom(String classRoom) {
        Student.classRoom = classRoom;
    }
}

注意】需要在get和set方法前加static,因为classRoom是静态成员变量,只能在静态方法中访问
4)构造对象时,构造方法中赋值(不推荐使用)

public class Student {
    private int sno;//学号
    public String sex;//性别
    public int score;//分数
    public String name;//姓名

    public static String classRoom ;

    public Student(int sno, String sex, int score, String name, String a) {
        this.sno = sno;
        this.sex = sex;
        this.score = score;
        this.name = name;
        classRoom = a;
    }
}

注意】这是构造方法,不要加任何修饰符如void之类的,可以加访问修饰限定符如public等
5)代码块初始化(使用较少)

【注意】
静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性,而静态成员变量不需要实例化对象来访问

2. 代码块

概念】使用 {}(一对大括号) 定义的一段代码称为代码块
分类】根据代码块定义的位置以及关键字,可分为以下四种:普通代码块、构造代码块、静态代码块和同步代码块

2.1 普通代码块

定义:方法内的代码块
在这里插入图片描述

2.2 构造代码块(实例代码块、非静态代码块)

定义:类内,方法外的代码块
作用:构造代码块一般用于初始化实例成员变量

public class Student {
    private int sno;//学号
    public String sex;//性别
    public int score;//分数
    public String name;//姓名

    public Student(int sno, String sex, int score, String name) {
        this.sno = sno;
        this.sex = sex;
        this.score = score;
        this.name = name;
        System.out.println("我是构造方法~");
    }

    {
        System.out.println("构造代码块/实例化代码块/非静态代码块");
    }
}

class Test {
    public static void main(String[] args) {
        Student s1 = new Student(123,"女",99,"小小");
    }
}

得到结果如下:
在这里插入图片描述
从结果我们可以看到,先打印的构造代码块里的内容,后打印构造方法里的内容,而不是看顺序打印
可以简单认为:编译器会把静态代码块的东西放在构造方法的最前面

2.3 静态代码块

定义:使用static修饰的代码块
作用:初始化静态成员数据以及提前准备一些数据

 static {
    classRoom = "L1210";
    System.out.println("静态代码块");
 }

注意
1)静态代码块只执行1次,无论生成多少个对象,类被加载就执行
2)实例化代码块依赖于对象,只有实例化对象时才会执行
3)一个类中包含多个静态代码块,编译器按照定义的先后执行

2.4 同步代码块

涉及到多线程

3. 内部类

内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类。

3.1 实例内部类

定义:未被static修饰的内部成员

public class Outclass {
    private String a;
    static int b;
    int c;
    public void method(){
        a = "hh";
        System.out.println(a);
    }
    // 实例内部类
    class Innerclass{
        int c;
        public void methodInner(){
            // 在实例内部类中可以直接访问外部类任意!!!外部类abc变量的修饰符都不同,任意访问!
            b = 666;
            method();
            a = "lala";
            System.out.println(a);
            // 如果外部类和实例内部类中具有相同名称成员时,优先访问内部类自己的成员
            c = 999;
            System.out.println(c);
            // 如果要访问外部类同名成员时候:外部类名称.this.同名成员名字
            Outclass.this.c = 300;
            System.out.println(Outclass.this.c);
        }
    }
    public static void main(String[] args) {
        System.out.println("有关实外部类的访问");
        // 外部类:对象创建以及成员访问
        Outclass outclass = new Outclass();
        System.out.println(outclass.a);
        System.out.println(Outclass.b);
        System.out.println(outclass.c);
        outclass.method();
        System.out.println("有关实例内部类的访问");
        // 1.要访问实例内部类中成员,必须要创建实例内部类的对象
        // 2.创建实例内部类对象时必须借助外部类
        // 3,创建实例内部类对象 依赖外部类的对象
        //方法1:
        Outclass.Innerclass innerClass1 = new Outclass().new Innerclass();
        // 上述语法比较麻烦,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
        //方法2:
        Outclass.Innerclass innerclass2 = outclass.new Innerclass();
        innerclass2.methodInner();
    }
}

注意
1)在实例内部类方法中可以直接访问外部类中的任何成员
2)外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象
3)实例内部类受public、private等访问限定符的约束
4)在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,需要:

外部类名称.this.同名成员 来访问

5)实例内部类对象必须在先有外部类对象前提下才能创建
6)实例内部类的非静态方法中包含一个指向外部类对象的引用

3.2 静态内部类

定义:被static修饰的内部成员

public class Outclass {
    private String a;
    static int b;
    int c;
    public void method1(){
        a = "hh";
        System.out.println(a);
    }

    public static void method2(){
        System.out.println(b);
    }

    // 静态内部类
    static class Innerclass{
        int c;
        public void methodInner(){
            // a = "lala";
            // c = 20;
            //编译失败 静态内部类中只能访问外部类的静态成员变量 a、b变量不是静态变量
            b = 100; //b可以访问,因为b被static修饰,是静态变量
            //method1();
            //编译失败 静态内部类中只能访问外部类的静态成员方法 method1不是静态方法
            method2();
        }
    }
    public static void main(String[] args) {

        //直接用外部类
        Outclass.Innerclass innerClass = new Outclass.Innerclass();
        innerClass.methodInner();
    }
}

注意
1)静态内部类中只能访问外部类中的静态成员
2)创建静态内部类对象时,不需要先创建外部类对象,因为静态不依赖对象

3.3 局部内部类

定义:外部类的方法体或者{}
局部内部类只能在其定义的位置使用,一般使用非常少

public class Outclass {
    public String a;
    // 局部内部类(在这个方法体中)
    public void method() {
    class Innerclass {
        public void methodInner() {
            System.out.println(a);
        }
    }
        Innerclass innerclass = new Innerclass();
        innerclass.methodInner();
    }
}

注意
1) 局部内部类只能在所定义的方法体内部使用
2)不能被修饰符修饰,如public、static等修饰符

3.4 匿名内部类

涉及到抽象类和接口
本期内容回顾~
在这里插入图片描述下期再见!一起加油呀~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/509248.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu20安装python3.10

1、添加 deadsnakes PPA 到源列表 add-apt-repository ppa:deadsnakes/ppa apt update 2、安装 apt install python3.10 3设置默认版本为 Python3.10 查看所有python版本 ls -l /usr/bin/python* update-alternatives --install /usr/bin/python3 python3 /usr/bin/pytho…

居里亚斩获金定奖,第13届广州定制家居展见证品牌实力飞跃

2024年3月30日,第13届广州定制家居展圆满落幕。 作为年度首场定制家居专业大展,第13届广州定制家居展的展览规模达到了100,000平方米,吸引了超过350,000人次的关注,以及800多家参展企业的参与。 在百花齐放的定制家居品类中&#…

物联网监控可视化是什么?部署物联网监控可视化大屏有什么作用?

随着物联网技术的深入应用,物联网监控可视化成为了企业数字化转型的关键环节。物联网监控可视化大屏作为物联网监控平台的重要组成部分,能够实时展示物联网设备的运行状态和数据,为企业管理决策和运维监控提供了有力的支持。今天,…

第45期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区,集成了生成预训练Transformer(GPT)、人工智能生成内容(AIGC)以及大语言模型(LLM)等安全领域应用的知识。在这里,您可以找…

使用Git处理Github中提交有冲突的pull request

前言: 为什么要写这篇文章,因为前段时间有一个开源的github中的项目有一个朋友提交了一个pr看了下是帮忙优化了下代码(十分感谢这位网友)。但是他提交的pr刚好和我的项目有许多的冲突导致无法自动合并,在github中提示…

[蓝鲸有奖征文]蓝鲸6.1 CMDB 事件推送的开源替代方案

本文来自腾讯蓝鲸智云社区用户:木讷大叔爱运维 背景 在蓝鲸社区“社区问答”帖子中发现这么一个需求: 究其原因,我在《不是CMDB筑高墙,运维需要一定的开发能力!》一文中已经介绍,在此我再简单重复下&#…

喜讯!全视通获评“医用气体行业优秀装备制造企业”称号

春意盎然,“渝”您相见。3月28日,“2024中国医学装备大会暨展览会”在重庆隆重启幕,本次展览会是我国医学装备领域政府部门、相关专家、头部企业深度参与的综合性展会,是先进技术最权威的展示平台之一,是引领创新发展的…

备战2024年中学生古诗文大会(初中组):单选题真题和独家解析

我们继续来做中学生古诗文大会(初中组)——简称初中生古诗文大会的一些真题,让大家了解初中生古诗文大会的考察内容和形式,并且提供了我独家的题目解析和答案,供初中的同学们学习和参考。 以下题目截取自我独家制作的在…

《基础设施即代码(IaC)》译者序

随着信息技术的飞速发展,我们对基础设施的理解也在不断深化。传统的基础设施往往被看作是硬件和软件的堆砌,而现在,基础设施的概念已经发生了巨大的变化。在当今这个信息化、数字化的时代,基础设施已经成为了企业和组织运行的核心…

Linux多进程通信(3)——详细说说共享内存原理及使用例程

1.共享内存原理及优缺点 共享内存的原理便是将相同的一片物理内存映射到进程A和进程B不同的逻辑地址空间,两个进程同时访问这块物理内存(共享内存)。 1)优点 共享内存是进程间通信访问速度最快。 例如消息队列,FIFO&…

喜尔康众多智慧酒店解决方案亮相上海酒店展,“十档妇洗”技术惊艳全馆

日前,2024上海国际酒店及商业空间博览会在上海新国际博览中心盛大举行,2000品牌同时亮相,引发行业广泛关注。 作为行业领先的智能家居企业,喜尔康30年来专注于为大家居行业提供智能化解决方案,此次参展展出了超静音智能…

ssm校园订餐系统

ssm校园订餐系统 一、项目简介 本项目是一套基于SSM实现的网上订餐系统 或 在线点餐系统 或 外卖点餐系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 详细介绍了网上订餐系统的实现,包括: 1.项目介绍 2.环境…

突破编程_前端_JS编程实例(分割窗体组件)

1 开发目标 分隔窗体组件旨在提供灵活的窗体分隔功能,支持横向分割与纵向分隔两种类型,并具备拖拽调整窗体比例的功能,同时提供最小比例设置,以防止窗体被过度缩小: 2 详细需求 2.1 分隔窗体类型 (1&…

Ant Design Vue中的table与pagination的联合使用

效果&#xff1a; 代码&#xff1a; <a-table:dataSource"dataSource":columns"columns":pagination"pagination"change"handleTableChange":scroll"{ x: 100%, y: 600 }"> </a-table> export default defin…

零基础入门实战深度学习Pytorch课程下载

本课程旨在帮助零基础学员掌握PyTorch深度学习框架。通过实战项目&#xff0c;学员将学习神经网络基础、模型训练和调优技巧。逐步掌握深度学习核心概念&#xff0c;为未来在人工智能领域打下坚实基础。 课程大小:2.6G 课程下载&#xff1a;https://download.csdn.net/downlo…

网络安全 | 什么是云安全?

关注WX&#xff1a;CodingTechWork 云安全-介绍 云安全是为了解决企业安全所面临的外部和内部威胁&#xff0c;它是一组程序和技术的集合。企业在实施其数字化转型策略&#xff0c;并将各种云端工具和服务纳入企业基础架构中时&#xff0c;需要云安全保障业务顺利进行。 云计…

CentOS7.9排查网络带宽高占用的情况

//显示全部网卡 ifconfig //安装iftop yum install iftop -y //设定监测的网卡 iftop -i eth0 按 P 显示 host 信息及端口信息。 按 D 切换是否显示远端目标主机的端口信息。

15 - grace序列处理 - 十三点滑动平均法

grace序列处理 -十三点滑动平均法 滑动平均是一种常用的平滑数据的方法,可以用于去除噪声或者提取趋势。十三点滑动平均是指使用窗口大小为13的滑动平均,应用于GRACE序列处理中可以去除周年项的影响。 十三点滑动平均的计算公式为: y [ n ] = ( x [ n − 6 ]

C++ | Leetcode C++题解之第6题Z字形变换

题目&#xff1a; 题解&#xff1a; class Solution { public:string convert(string s, int numRows) {int n s.length(), r numRows;if (r 1 || r > n) {return s;}string ans;int t r * 2 - 2;for (int i 0; i < r; i) { // 枚举矩阵的行for (int j 0; j i &l…

ARM64架构栈帧以及帧指针FP

文章目录 前言一、arm64架构寄存器简介1.1 异常等级1.2 通用寄存器1.3 ARM64架构ABI 二、ARM64架构函数调用标准2.1 AArch64过程调用标准简介2.2 通用寄存器中的参数 三、demo分析3.1 main函数3.2 funb3.3 funa 四、栈帧总结五、demo演示参考资料 前言 这篇文章描述了 x86_64架…