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. 静态函数;
函数是对外提供的功能,但是函数是否用静态修饰就参考一点,这个函数是否访问到对象的特有数据。
简单点说,从源代码看,该功能是否需要访问非静态的成员变量,如果需要,该功能就是非静态的。如果不需要,就可以将该功能定义成静态的,当然也可以定义成非静态,但是非静态需要被对象调用,而仅创建对象调用非静态的方法,没有访问特有数据,该对象的创建是没有意义的。
- 关键字static的作用
- 关键字static的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- Static关键字的作用
- 关键字static的作用
- 关键字static的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- 关键字static的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- 关键字static的作用
- 新特性:TabLayout动态添加条目
- checkbox树显示,全选和反选
- csv 中 数值被自动转换成科学计数法 的问题 excel打开后数字用科学计数法显示且低位变0的解决方法
- Android面试常见问题及解答
- PHP--swoole
- static关键字的作用
- Hello world!
- eclipse jdk配置与安装后错误 java was started but returned exit code=13
- 基于Cesium的一些demo
- web数据存储
- Ubuntu 12.04 LTS 添加中文输入法
- 替换空格
- JavaWeb Servlet 入门使用
- HTML里的转义字符