static静态变量
static静态变量特点:
- 该变量叫做静态变量,被这个类所有对象共享
- 不属于对象,属于类
- 随着类的加载而加载,优先于对象而存在
底层原理解释:
当定义类的时候,方法区会开辟一块类的内存空间,此时堆就会为静态变量开辟一块内存空间。
当创建对象的时候,堆会为对象开辟一块区别于静态变量的独立内存空间,同时对象会记录静态变量的内存地址,而栈则为对象的变量名开辟一块内存空间,同时把对象的地址赋值给该变量的内存空间,当你通过对象调用类中的方法时,方法会被加载进栈,同时该方法的内存空间会记录调用对象的内存空间,当你调用这个方法的时候,方法会通过记录的调用者对象的地址去查询堆中对应对象的成员变量,成员变量再通过记录的静态变量地址查询静态变量的值。
就是由于静态变量有着区别于对象的独立内存空间,当某个对象对静态变量进行修改时,由于所有对象都关联同一块静态变量地址,其他对象再次调用静态变量的时候就会得到被改变了的静态变量值。
调用方式:
- 类名调用(推荐)
- 对象名调用
由以上分析,我们不难得出,我们更推荐使用类名调用静态变量,因为静态变量不属于某一个对象。
static关键字的注意事项
- 静态方法只能访问静态变量和其他的静态方法
- 非静态方法可以访问静态变量或者静态方法,也可以访问非静态的成员变量和非静态的成员方法
- 静态方法中是没有this关键字
总结:静态只能调用静态,非静态可以调用所有,静态方法无this
底层逻辑解释:
当类进入到方法区的时候,静态变量就已经加载到堆区,当执行main方法的时候,main方法加载到栈区,同时main方法当中的静态方法也加载到栈中,但静态方法是没有this关键字的,因此静态方法内没有记录调用者的内存地址,在方法当中我要获取两个变量分别是非静态变量name和静态变量teacherName,,由于现在堆中还不存在对象,所以此时name会报错,就算此时已经有了对象,但是由于静态方法中没有this关键字,它也不无法获取到对象的name。
这里会出现一个疑惑,既然静态方法不存在this关键字,也就无法获取非静态变量的地址,那么他是怎么获取到静态变量的地址的?
解释:静态方法没有this,但它根本不需要this就能找到静态变量,因为静态方法编译时就绑定了静态变量的位置
如果在静态方法中,定义了局部变量(和类内的静态变量同名),要想访问类的静态变量,必须写类名,静态方法内局部变量 B 会遮蔽(覆盖)类静态变量 B,默认取局部;(就近原则)要访问类静态变量必须用 类名.B。
从逻辑的角度其实也很好理解,static方法是通用的,如果 static 方法能直接访问非 static 变量,那就会出现巨大矛盾:
- 静态方法被调用时,根本没有任何对象上下文
- 那它到底访问哪个对象的成员变量?
- 是对象 A?对象 B?还是对象 C?
→ 完全无法确定,逻辑上根本不成立!
浙公网安备 33010602011771号