一文讲清楚static关键字
static能修饰的地方
- 静态变量 - 静态变量: 又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它;静态变量在内存中只存在一份。
- 实例变量: 每创建一个实例就会产生一个实例变量,它与该实例同生共死。
 
- 静态方法 - 静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法(abstract)。 
- 只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字。 
 
- 静态语句块 - 静态语句块在类初始化时运行一次。
 
- 静态内部类 - 非静态内部类依赖于外部类的实例,而静态内部类不需要。 
- 静态内部类不能访问外部类的非静态的变量和方法。 
 
- 静态导包 - 在使用静态变量和方法时不用再指明 ClassName,从而简化代码,但可读性大大降低。
 
初始化顺序
- 静态属性,静态代码块。 
- 普通属性,普通代码块。 
- 构造方法。 
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,欢迎关注~
一文讲清楚static关键字的更多相关文章
- 理解Java中的final和static关键字
		回顾这两个关键字前,先考虑一个问题: Static变量存储在JVM中的位置,或者说static变量是如何被加载的? JVM会把类的静态方法和静态变量在类加载的过程中读入方法区(Method Area) ... 
- static关键字的用法和main函数
		一.static关键字:静态的,它可以修饰成员变量和成员方法 1.修饰成员变量的情况,当类所属对象中存在共享数据时,我们就可以把数据对应的属性定义为静态的,这里的共享数据是对象数据相同,而不是拥有相同 ... 
- java中构造方法和this,static关键字
		构造方法: 构造方法是一种特殊的方法,用于创建该类的对象,对对象的数据进行初始化 格式如下: [修饰符] 类名(形参列表){ 方法体 } 特点 A:方法名和类名相同 B:没有返回值类型,连void都 ... 
- C++从静态对象的初始化顺序理解static关键字
		问题 首先考虑一个全局变量的初始化顺序问题 在头文件1中: extern int b; ; 在头文件2中: extern int a; ; 源文件中包含了头文件1和头文件2,这种情况下a和b可能的值是 ... 
- static关键字真能提高Bean的优先级吗?答:真能
		生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ... 
- 浅谈Static关键字
		1.使用static关键字声明的属性为全局属性 未使用static关键字指定city之前,如果需要将Tom,Jack,Mary三人的城市均改成Beijing,需要再次声明三次对象的city为Beiji ... 
- (转)Java中的static关键字解析
		转载: http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: &q ... 
- PHP的final关键字、static关键字、const关键字
		在PHP5中新增加了final关键字,它可以加载类或类中方法前.但不能使用final标识成员属性,虽然final有常量的意思,但在php中定义常量是使用define()函数来完成的. final关键字 ... 
- Java Static关键字详解
		提起static关键字,相信大家绝对不会陌生,但是,想要完全说明白,猛的一想,发现自己好像又说不太明白... ...比方说,昨天被一个同学问起的时候... ... 当然,不是所有人都像我一样学艺不精的 ... 
- 关于Java中的static关键字
		Java中的 static 关键字,确实是一个关键的字(key word),今天就来总结一下它的用法,说说为什么关键. Java中的 static 关键字主要是用来做内存管理的.理解了这句话才能够比较 ... 
随机推荐
- Centos  下Rabbit MQ 常用操作指令 汇总
			1.rabbitmq 服务的启动停止. service rabbitmq-server start service rabbitmq-server stop 重启命令需要依次执行 stop 再 sta ... 
- 复习-jQuery
			咱就是说,发现了一个更好的方法每次把效果图制作成了一个gif,另外推荐个免费软件GIFcam很方便制作gif图,毕竟js是一门动态交互的语言对吧,没有动态的图那就是没有灵魂的所以以后就用这种方式来上传 ... 
- Git ignore 忽略文件不起作用
			前提:拉取了项目上的代码,或者自己本地已经提交过了的文件.然后在 .gitignore 文件中添加了过滤,但是不管用,还是可以追踪 解决方案: 1.先删除本地的文件(可以备份到其他文件夹外) 2.然后 ... 
- 用python处理html代码的转义与还原-转
			本篇博客来源: 用python处理html代码的转义与还原 'tag>aaa</tag> # 转义还原 str_out = html.unescape(str_out) print( ... 
- Windows安装OnlyOfiice教程
			1.OnlyOffice介绍 OnlyOffice 是一个在线创建.编辑和协作文档的服务. 2.Docker介绍 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移 ... 
- git使用教程及常用命令
			1.初次本地git连接远程仓库,并提交代码到远程仓库 第一步 码云上创建仓库 第二步 在需要上传的项目处右键-->git bush here 第三步 初始化本地git库 git init 设定 ... 
- 国内版Unity 2023编辑器无法切换到DX12模式的解决方法
			2024.7.4更新:至6000.0.5f1c1,此问题已修复 在{安装目录}\Editor里(也就是Unity安装的根目录)建立一个名叫D3D12的文件夹. 去{安装目录}\Editor\Data\ ... 
- Nuxt.js 错误侦探:useError 组合函数
			title: Nuxt.js 错误侦探:useError 组合函数 date: 2024/7/14 updated: 2024/7/14 author: cmdragon excerpt: 摘要:文章 ... 
- oeasy教您玩转vim - 14 - #  行头行尾
			行头行尾 回忆上节课内容 我们这次了解了 大词 和 小词 小词 就是我们常规意义的词 被 =." 等标点分开的词 大词 里面包括了 =." 等标点 只能被空格.tab.换行分割 W ... 
- 对于同一个项目,同时将其git到GitHub和Gitee
			对于同一个项目,你可以同时将其git到GitHub和Gitee.这通常通过配置多个远程仓库地址来实现.以下是一步步的操作指南: 一.在GitHub和Gitee上创建仓库 GitHub: 登录GitHu ... 
