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

news2024/11/24 18:25:47

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

在这里插入图片描述

文章目录

  • 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 匿名内部类

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记一次由gzip引起的nginx转发事故

故事背景 书接前几篇文章,仍然是交付甲方遇到的一个特殊诉求,从而引发了本期的事故。甲方的诉求是前端的请求过来,需要加密,但是要经过waf,必须要求是请求明文,那就要在waf和nginx之间做一个解密前置应用处…

【3】3道链表力扣题:删除链表中的节点、反转链表、判断一个链表是否有环

3道链表力扣题 一、删除链表中的节点🌏 题目链接📕 示例🍀 分析💻 代码 二、反转链表🌏 题目链接📕 示例🍀 分析① 递归② 迭代 三、判断一个链表是否有环🌏 题目链接📕 …

学习transformer模型-Input Embedding 嵌入层的简明介绍

今天介绍transformer模型的Input Embedding 嵌入层。 背景 嵌入层的目标是使模型能够更多地了解单词、标记或其他输入之间的关系。 从头开始嵌入Embeddings from Scratch 嵌入序列需要分词器tokenizer、词汇表和索引,以及词汇表中每个单词的三维嵌入。Embedding a s…

git clone 后如何 checkout 到 remote branch

what/why 通常情况使用git clone github_repository_address下载下来的仓库使用git branch查看当前所有分支时只能看到master分支,但是想要切换到其他分支进行工作怎么办❓ 其实使用git clone下载的repository没那么简单😥,clone得到的是仓库…

一个 hipsolver 特征值示例

1,原理 通过雅可比旋转,对对称矩阵计算特征值和特征向量; 通过初等正交变换,每次把其中一个非主对角元素消成零,最终只剩主对角线非零元素为特征值,同时把初等变换累积下来,构成特征向量。 2&a…

使用1panel部署Ollama WebUI(dcoekr版)浅谈

文章目录 说明配置镜像加速Ollama WebUI容器部署Ollama WebUI使用问题解决:访问页面空白 说明 1Panel简化了docker的部署,提供了可视化的操作,但是我在尝试创建Ollama WebUI容器时,遇到了从github拉取镜像网速很慢的问题&#xf…

Java反射系列(3):从spring反射工具ReflectionUtils说起

传送门 在比较早的时候,就讨论过java反射的一些用法及概念: Java反射系列(1):入门基础 以及反射的基石Class对象! Java反射系列(2):从Class获取父类方法说起 今天就从工作中实际的例子来看看反射的应用。 兼容…

pytest--python的一种测试框架--request请求加入headers

一、request headers中的cookie和session机制的作用与区别 Cookie 和 Session 是两种在客户端和服务器之间保持状态的技术。HTTP 协议本身是无状态的,这意味着服务器无法从上一次的请求中保留任何信息到下一次请求。Cookie 和 Session 机制就是为了解决这个问题。 …

240330-大模型资源-使用教程-部署方式-部分笔记

A. 大模型资源 Models - Hugging FaceHF-Mirror - Huggingface 镜像站模型库首页 魔搭社区 B. 使用教程 HuggingFace HuggingFace 10分钟快速入门(一),利用Transformers,Pipeline探索AI。_哔哩哔哩_bilibiliHuggingFace快速入…

遥感数字图像处理的学习笔记

相关链接: 遥感数字图像处理实验教程(韦玉春)--部分实验问题回答 目录 1.什么是图像,什么是数字图像? 2.什么是遥感数字图像?模拟图像(照片)与遥感数字图像有什么区别? 3.什么是遥感数字图像…

小小狠招:巧妙使用HANA数据库的jdbc driver

SAP旗下的HANA数据库,实际上是分为两个系列进行发布,一种是基于本地部署的称之为HANA Platform。另一种是面向Cloud平台的,称之为HANA Cloud。 在实际使用当用,因为两者基本上共用同一代码库,除个别地方略有差异以外&…

C++要学到什么程度才能找到实习?

在考虑 C 学习到何种程度可以找到实习时,以下是一些具体的方向和建议。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给个评论222,私信22,我…

HarmonyOS 应用开发之模型切换

本文介绍如何将一个FA模型开发的声明式范式应用切换到Stage模型,您需要完成如下动作: 工程切换:新建一个Stage模型的应用工程。 配置文件切换:config.json切换为app.json5和module.json5。 组件切换:PageAbility/Serv…

如何计算KST指标,昂首资本一个公式计算

在上一篇文章中,Anzo Capital昂首资本和各位投资者一起了解了KST指标,今天我们继续分享如何计算KST指标。 首先投资者可以在时间范围9、12、18和24分析变化率值。 前三个值(时间帧9、12、18)用EMA 26平滑,最后一个值用EMA 39平滑。 然后&…

AndroidStudio出现类似 Could not create task ‘:app:ToolOperatorDemo.main()‘. 错误

先看我们的报错 翻译过来大概意思是:无法创建任务:app:ToolOperatorDemo.main()。 没有找到名称为“main”的源集。 解决方法&#xff1a; 在.idea文件夹下的gradle.xml文件中 <GradleProjectSettings>标签下添加<option name"delegatedBuild" value"f…

前端小白如何理解mvc mvp mvvm

架构、框架、设计模式是都是啥&#xff1f; 架构&#xff1a;抽象出来不同组织或者对象亦或是简单组件&#xff0c;根据需求和各个单元的功能&#xff0c;进行组合排列。 从而完成系统的运行或者是实现目标。 框架&#xff1a;使用什么样的规则&#xff0c;什么样的开发语言&…

政安晨:【Keras机器学习实践要点】(十)—— 自定义保存和序列化

目录 导言 涵盖的API Setup 状态保存自定义 构建和编译保存自定义 结论 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在…

2024年京东云主机租用价格_京东云服务器优惠价格表

2024年京东云服务器优惠价格表&#xff0c;轻量云主机优惠价格5.8元1个月、轻量云主机2C2G3M价格50元一年、196元三年&#xff0c;2C4G5M轻量云主机165元一年&#xff0c;4核8G5M云主机880元一年&#xff0c;游戏联机服务器4C16G配置26元1个月、4C32G价格65元1个月、8核32G费用…

速腾聚创上市后首份财报:冲击年销百万台,押注人形机器人

作者 |老缅 编辑 |德新 港股「激光雷达第一股」速腾聚创&#xff0c;交出了上市后的首份业绩报告。 3月27日&#xff0c;速腾聚创发布了2023年度财报。 报告期内&#xff0c;公司迎来高速的业务增长——2023年总收入达到人民币11.2亿元&#xff0c;同比增长达到111.2%。这主…

Artplayer视频JSON解析播放器源码|支持弹幕|json数据模式

全开源Artplayer播放器视频解析源码&#xff0c;支持两种返回模式&#xff1a;网页播放模式、json数据模式&#xff0c;json数据模式支持限制ip每分钟访问次数UA限制key密钥&#xff0c;也可理解为防盗链 &#xff0c;本播放器带弹幕库。 运行环境 推荐使用PHP8.0 redis扩展…