首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

一文讲清楚static关键字

编程知识
2024年08月23日 20:02

static能修饰的地方

  1. 静态变量

    • 静态变量: 又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它;静态变量在内存中只存在一份。
    • 实例变量: 每创建一个实例就会产生一个实例变量,它与该实例同生共死。
  2. 静态方法

    • 静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法(abstract)。

    • 只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字。

  3. 静态语句块

    • 静态语句块在类初始化时运行一次。
  4. 静态内部类

    • 非静态内部类依赖于外部类的实例,而静态内部类不需要。

    • 静态内部类不能访问外部类的非静态的变量和方法。

  5. 静态导包

    • 在使用静态变量和方法时不用再指明 ClassName,从而简化代码,但可读性大大降低。

初始化顺序

  1. 静态属性,静态代码块。

  2. 普通属性,普通代码块。

  3. 构造方法。

public class InitOrder {

    // 静态属性
    private static String staticField = getStaticField();

    // 静态代码块
    static {
        System.out.println(staticField);
        System.out.println("静态代码块初始化");
    }

    // 普通属性
    private String field = getField();

    // 普通代码块
    {
        System.out.println(field);
        System.out.println("普通代码块初始化");
    }

    // 构造方法
    public InitOrder() {
        System.out.println("构造方法初始化");
    }

    // 静态方法
    public static String getStaticField() {
        String staticFiled = "静态属性初始化";
        return staticFiled;
    }

    // 普通方法
    public String getField() {
        String filed = "普通属性初始化";
        return filed;
    }

    public static void main(String[] argc) {
        new InitOrder();
    }

    /**
     *      静态属性初始化
     *      静态代码块初始化
     *      普通属性初始化
     *      普通代码块初始化
     *      构造方法初始化
     */
}

静态方法和变量能否被继承

先说结论:能

父类A:

public class A {
    public static String staticStr = "A静态属性";
    public String nonStaticStr = "A非静态属性";
    public static void staticMethod(){
        System.out.println("A静态方法");
    }
    public void nonStaticMethod(){
        System.out.println("A非静态方法");
    }
}

子类B:

public class B extends A{

    public static String staticStr = "B改写后的静态属性";
    public String nonStaticStr = "B改写后的非静态属性";

    public static void staticMethod(){
        System.out.println("B改写后的静态方法");
    }

    @Override
    public void nonStaticMethod() {
        System.out.println("B改写后的非静态方法");
    }
}

子类C:

public class C extends A{
}

测试:

public class Demo {
    public static void main(String[] args) {
        C c = new C();//C的引用指向C的对象
        System.out.println(c.nonStaticStr);//A非静态属性
        System.out.println(c.staticStr);//A静态属性
        c.nonStaticMethod();//A非静态方法
        c.staticMethod();//A静态方法
        //推出静态属性和静态方法可以被继承

        System.out.println("-------------------------------");

        A c1 = new C();//A的引用指向C的对象
        System.out.println(c1.nonStaticStr);//A非静态属性
        System.out.println(c1.staticStr);//A静态属性
        c1.nonStaticMethod();//A非静态方法
        c1.staticMethod();//A静态方法
        //推出静态属性和静态方法可以被继承

        System.out.println("-------------------------------");
        B b = new B();//B的引用指向B的对象
        System.out.println(b.nonStaticStr);//B改写后的非静态属性
        System.out.println(b.staticStr);//B改写后的静态属性
        b.nonStaticMethod();//B改写后的非静态方法
        b.staticMethod();//B改写后的静态方法

        System.out.println("-------------------------------");
        A b1 = new B();//A的引用指向B的对象
        System.out.println(b1.nonStaticStr);//A非静态属性
        System.out.println(b1.staticStr);//A静态属性
        b1.nonStaticMethod();//B改写后的非静态方法
        b1.staticMethod();//A静态方法
        //结果都是父类的静态方法,说明静态方法不可以被重写,不能实现多态
    }
}

注意

静态变量尤其要注意并发问题。因为静态变量在Java中是类级别的变量,它们被所有类的实例共享。由于静态变量是共享资源,当多个线程同时访问和修改静态变量时,就会引发并发问题。

总结

  • 子类会继承父类的静态方法和静态变量,但是无法对静态方法进行重写

  • 子类中可以直接调用父类的静态方法和静态变量

  • 子类可以直接修改(如果父类中没有将静态变量设为private)静态变量,但这是子类自己的静态变量。

  • 子类可以拥有和父类同名的,同参数的静态方法,但是这并不是对父类静态方法的重写,是子类自己的静态方法,子类只是把父类的静态方法隐藏了。

  • 当父类的引用指向子类时,使用对象调用静态方法或者静态变量,是调用的父类中的静态方法或者变量(这比较好理解,因为静态方法或变量是属于类的,而引用指向的是一个对象,对象中并不会包含静态的方法和属性)。也就是说,失去了多态。

  • 当子类的引用指向子类时,使用对象调用静态方法或者静态变量,就是调用的子类中自己的的静态方法或者变量了。

关于作者

来自一线程序员Seven的探索与实践,持续学习迭代中~

本文已收录于我的个人博客:https://www.seven97.top

公众号:seven97,欢迎关注~

From:https://www.cnblogs.com/seven97-top/p/18377083
本文地址: http://www.shuzixingkong.net/article/1384
0评论
提交 加载更多评论
其他文章 平衡搜索树-AVL树 图文详解 (万字长文)
目录AVL树AVL树的概念AVL树节点的定义:AVL树的插入基本情况分析平衡因子对应的操作旋转操作分析需要旋转的情况结论4种旋转操方法与特征6种双旋平衡因子特征代码实现四种旋转实现插入操作实现树高度与是否平衡树判断实现其他实现插入验证BenchMark环境测试工具和方法测试结果: AVL树 AVL树
平衡搜索树-AVL树  图文详解  (万字长文) 平衡搜索树-AVL树  图文详解  (万字长文) 平衡搜索树-AVL树  图文详解  (万字长文)
Go 互斥锁 Mutex 源码分析 (一)
原创文章,欢迎转载,转载请注明出处,谢谢。 0. 前言 锁作为并发编程中的关键一环,是应该要深入掌握的。 1. 锁 1.1 示例 实现锁很简单,示例如下: var global int func main() { var mu sync.Mutex var wg sync.WaitGroup for
Go 互斥锁 Mutex 源码分析 (一) Go 互斥锁 Mutex 源码分析 (一)
WPF 模仿前端大佬写一个Hover效果
先看一下效果吧: 原博主的地址:【动画进阶】神奇的卡片 Hover 效果与 Blur 的特性探究 - ChokCoco - 博客园 (cnblogs.com) 原效果是一个css效果,我们采用WPF的方式模仿一下 因为技术有限,没有原博主的那么好看,毕竟盗版永远比不过原版... 然后这里看一下盗版的
WPF 模仿前端大佬写一个Hover效果 WPF 模仿前端大佬写一个Hover效果 WPF 模仿前端大佬写一个Hover效果
JuiceFS 在多云架构中加速大模型推理
在大模型的开发与应用中,数据预处理、模型开发、训练和推理构成四个关键环节。本文将重点探讨推理环节。在之前的博客中,社区用户 BentoML 和贝壳的案例提到了使用 JuiceFS 社区版来提高模型加载的效率。本文将结合我们的实际经验,详细介绍企业版在此场景下的优势。 下图是一个典型的大模型推理服务的
JuiceFS 在多云架构中加速大模型推理 JuiceFS 在多云架构中加速大模型推理 JuiceFS 在多云架构中加速大模型推理
线性dp:编辑距离
编辑距离 本题与力扣72.编辑距离题意一样,阅读完本文可以尝试leetcode72. 力扣题目链接 题目叙述 输入两个字符串a,b。输出从字符串a修改到字符串b时的编辑距离 输入 NOTV LOVER 输出 4 题目解释: 动态规划思路 这个问题显然是一个最优解问题,我们可以考虑动态规划的思路,那么
线性dp:编辑距离 线性dp:编辑距离 线性dp:编辑距离
关于对 Tomcat 进行小版本升级的快速解决方案
1、背景描述 原来的 Tomcat 在部署时,使用的是最新的版本 9.0.40 。 经过一段时间后,在原来的 Tomcat 版本中,发现存在漏洞。 因此,需要将旧版本(9.0.40)升级到没有漏洞的新版本(9.0.93)。 2、查看Tomcat的版本信息 如上图所示,在 tomcat 的 bin 目
关于对 Tomcat 进行小版本升级的快速解决方案 关于对 Tomcat 进行小版本升级的快速解决方案 关于对 Tomcat 进行小版本升级的快速解决方案
Python的OpenCV转换图像大小
本文简要介绍了Python的OpenCV转换图像大小的方法,本文加载一个图像文件,将其大小转换为指定的宽度和高度,然后显示并保存转换后的图像。
全网最适合入门的面向对象编程教程:37 Python常用复合数据类型-列表和列表推导式
在Python中,列表是一个非常灵活且常用的复合数据类型。它允许存储多个项,这些项可以是任意的数据类型,包括其他列表。列表推导式是一种简洁的方式来创建和操作列表。
全网最适合入门的面向对象编程教程:37 Python常用复合数据类型-列表和列表推导式 全网最适合入门的面向对象编程教程:37 Python常用复合数据类型-列表和列表推导式 全网最适合入门的面向对象编程教程:37 Python常用复合数据类型-列表和列表推导式