static关键字的作用

来源:互联网 发布:复活岛巨人像 知乎 编辑:程序博客网 时间:2024/06/06 17:32

static是一个修饰符,用于修饰成员(成员变量和成员函数):

1.当static修饰成员变量:

        static修饰成员变量是解决数据的共享问题,static修饰的数据是每个对象共享 的数据。如果所有对象中某一个属性的值是一样的,那么在内存中会造成大量的数据重复,所以我们可以把这个重复的数据拿出来,放在一个公共的地方,就用static修饰,如图:

                  

            这个公共的地方不在堆里也不在栈里,在方法区的静态区里,静态区中放一些静态变量和静态方法。而被静态修饰的变量和方法了一种调用方式:用类名调用。那么静态变量于成员变量的区别是什么呢?

首先明确一点,类类型变量与类变量不是一码事:类类型变量是由类定义的变量,类变量就是静态变量。

(1)    两个变量的生命周期不同。(也是静态的弊端,生命周期太长,但是也好过占用内存)

成员变量随着对象的创建而存在,随着对象的回收而被释放;

静态变量随着类的加载而存在,会随着类的消失而消失。虚拟机结束类才会消失,类本身是一个对象,在内存里面也是按照对象的形式存储的,只不过可以通过这个类对象创建很多对象来封装具体的数据,当类的数据过多的时候,垃圾回收机制可以对他进行回收,判定方式是如果类很长时间不用就把它清除,当再次使用再重新加载。

(2)   调用方式不同

    成员变量只能被对象调用;

    静态变量可以被对象调用,还可以被类名调用。(不管有没有对象,都建议用类名调用,因为这是静态的专属调用方式,可阅读性强,让人看了一目了然,知道这是静态变量)。

(3)    别名不同

成员变量也称为实例变量;

静态变量也称为类变量。

(4)  数据存储位置不同

成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据;

静态变量数据存储在方法区(也叫共享区,数据区·····翻译的名字多着呢,还记得之前五个区不?)的静态区中,所以也叫对象的共享数据。(方法存在方法区,调用时进栈)

2.当static修饰成员函数:

       当static修饰成员函数,这个函数就成为了一个静态函数,静态函数可以直接访问静态成员,静态方法,但是如果要访问成员方法,只能通过对象访问。我们来解释一下这句话的意思。刚刚我们提到,静态变量和静态方法都是存放在静态区中的,会随着类的加载而加载,也就是说静态成员的出现比对象要早,所以如果静态函数要调用非静态方法,我们必须要在静态函数内部创建一个对象.,以保证这个对象是和静态方法一起出现的,这样才能使用这个对象访问非静态的方法和变量。

1.      静态方法只能访问静态成员(包含成员变量成员函数),非静态既可以访问静态又可以访问非静态。

2.      静态方法中不可以定义this过super关键字。(因为用类名调用静态方法时没有对象,所以this没有指向,所以写this是会报错的 )

三句话图解static在内存中的姿势:

                                                  

首先我们先来分析这段代码:

当我们执行StaticDemo2的字节码文件的时候,这个类被加载进内存,然后进行空间的开辟,不同种类数据存放在不一样的地方。方法区里有一个静态区,存放静态方法和数据,非静态区里存放非静态的方法和数据,它们都是被共享的。非静态区里面都有一个this所属,内容只能被对象调用;静态区里有一个所属是自己的类名,没有this,this是不能写在静态方法里的,所以此时,当我们调用这个StaticDemo2类的时候,内存的加载如下:

                                              

当运行到主函数的时候,主函数进栈:

     第一句话:使用到了Person类,此时找classPath路径下是否有Person.class文件,如果没有设置classPath,默认在当前路径下找,找到Person文件后加载Person类,加载完毕后,运行method()方法,method()方法进栈,语句执行完毕,运行默认的return语句,方法出栈。

                                                                   

第二句话:在主函数中定义一个Person类型的变量p,在堆中创建一个新对象,为对象分配地址,堆内存对对象进行数据初始化,然后传参数进行构造函数初始化,构造函数进栈,执行完毕弹栈。

 

                                                         

第三句话:p.show()在编译运行之前都要检查是否有show()方法,如果有show()方法,show()方法进栈,并且show()方法是非静态的方法,所以show()方法里也应该有默认的this引用,此时this的值是所属的函数的调用对象的值,在输出语句中可以通过类的所属找到country,通过this找到name和age。执行完毕后结束函数。

                                                                

什么时候使用静态?

静态只能修饰成员(成员变量,成员函数)

1. 静态变量;

不加静态是在对象里,加了静态是在方法区里;

不加静态是对象特有,加了静态对象共有。

当分析对象中所具备的成员变量的值都是相同的,这个成员就可以被静态修饰,但是如果有一个值不是相同的或者可以被改变,那就不可以用静态。

只要数据在对象中都是不同的,就是对象的特有数据,必须存储在对象中,是非静态的;

如果是相同的数据,对象不需要做修改,只需要使用即可,不需要存储在对象中。(如存在对象中也可以,但是会造成空间的浪费,但是也不可以都用静态,这样问题分析不好,生命周期过长)

2. 静态函数;

函数是对外提供的功能,但是函数是否用静态修饰就参考一点,这个函数是否访问到对象的特有数据。

简单点说,从源代码看,该功能是否需要访问非静态的成员变量,如果需要,该功能就是非静态的。如果不需要,就可以将该功能定义成静态的当然也可以定义成非静态,但是非静态需要被对象调用,而仅创建对象调用非静态的方法,没有访问特有数据,该对象的创建是没有意义的。





1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 近视镜眼镜腿断了该怎么办 老师把学生的眼镜打坏了怎么办 生死狙击忘了密保改不了密码怎么办 我叫mt狂猎之弓怎么办 你能利用你的弱点打击你怎么办 研控两相混合伺服电机反转怎么办? 战地一要我升级显卡驱动怎么办 刺客信条兄弟会存档损坏了怎么办 电脑上所有软件和文件被删了怎么办 电脑显示文件已打开无法删除怎么办 金立手机桌面停止运行黑屏怎么办 苹果平板电脑玩游戏黑屏闪退怎么办 电脑开机时显示无法找到入口怎么办 我的世界显示网络玩不了的怎么办啊 网页被设置成不可以到下一页怎么办 小天鹅热水器排污螺丝拧不动怎么办 葡萄霜霉严重叶片开始发焦了怎么办 上海高架gps定位信号差怎么办 老公开车技术不行还非要开怎么办 我偷了同学手机被发现应该怎么办 没满月孩孑4天没大便了怎么办 电机轴总是从皮带轮处断裂怎么办 天花板吊顶里的热水管经常坏怎么办 摩托车油箱下面的废油管漏油怎么办 大修机械压力机轴取不下来怎么办 萌侠传说账号密码没了怎么办 车子前保护杠塑料刮花了怎么办 糖猫电话手表关机了找不到了怎么办 小天才电话手表被洗衣机洗了怎么办 小天才电话手表放洗衣机洗了怎么办 小天才电话手表泡水了怎么办 小天才电话手表联不上网怎么办 肺炎用激素治疗后肚子大了怎么办 8岁以下儿童总是低烧不退怎么办? 微博里面的视频不能改变方向怎么办 朗逸导航倒车一体机死机了怎么办 乐淘乐电话手表的二维码没了怎么办 艾蔻儿童手表二维码丢了怎么办 糖猫儿童智能手表二维码丢了怎么办 海信电视用遥控器关了打不开怎么办 创维4k电视遥控器按键坏了怎么办