首先,什么是变量?
变量就是内容可以改变的量,与常量相对应。
类变量与实例变量
1、类变量,是与类相联系的变量,在类中增加static修饰符进行定义,所以又称为静态变量。类变量不仅可以直接通过类名+点操作符+变量名来操作,也可以通过类的实例+点操作符+变量来操作,大多数情况下,采用前者操作方式。
2、实例变量,是与类的实例相联系的变量。实例变量只能通过类名的实例+点操作符+变量来操作。
与类变量和实例变量相对应的一组概念就是类方法和实例方法,类方法与类相联系,实例方法与类的实例相联系。需要注意的是,静态方法是不能调用实例变量的。因为实例变量随着对象的创建而存在,随着对象的回收而释放,而静态方法是先于对象存在的。此外,静态方法中不能使用this,super关键字。因为this代表对象,而静态在时,有可能没有对象,所以this无法使用。
具体说来,类变量与实例变量主要由以下几点区别:
- 生命周期
实例变量随着对象的创建而存在,随着对象的回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。 - 调用方式
实例变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。 - 存储位置
实例变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
访问权限
访问权限指的是本类及本类内部的成员(成员变量、成员方法、内部类)对其他类的可见性,即这些内容是否允许其他类访问。
Java 中一共有四种访问权限控制,其权限控制的大小情况是这样的:public > protected > default(包访问权限) > private ,具体的权限控制看下面表格。
作用域 | 当前类 | 同一包内 | 子孙类(不同包) | 其他包 |
---|---|---|---|---|
public | √ \surd √ | √ \surd √ | √ \surd √ | √ \surd √ |
protected | √ \surd √ | √ \surd √ | √ \surd √ | × \times × |
default | √ \surd √ | √ \surd √ | × \times × | × \times × |
private | √ \surd √ | × \times × | × \times × | × \times × |
小测试
那么,下面这一段代码编译是否可以通过呢?
class Wallet {
private int amount;
public void loanTo(Wallet that) {
that.amount += this.amount;//编译可以通过吗?
amount = 0;
}
public static void main(String[] args) {
Wallet w = new Wallet();
w.amount = 100;//编译可以通过吗?
w.loanTo(w);
}
}
答案是可以的。因为amount虽然是private的,但代码位于该类中,所以可以通过。
但如果在该类下面再添加一个类:
class Person {
private Wallet w;
public int getNetWorth() {
return w.amount;
}
public boolean isBroke() {
return Wallet.amount == 0;
}
}
静态检查会立即报错:The field Wallet.amount is not visible