内筒概览
1. 创建对象示意图
创建对象示意图
左边为栈(栈帧是指栈里的一小块空间),右边为堆。
所谓栈可以理解为一本书的目录,而堆为这本书的正文部分。即真正的对象(正文)是存在堆里面的,而栈里只是保存这个对象的地址(第几页)。
编号3中的主方法public static void main(String[] args){}是所有程序的入口。没有主方法程序是运行不了的。
2. 静态关键字static
上图中有个叫静态区的空间,即static area,凡是被static修饰的方法与变量都存于此处,即静态变量与静态方法,也叫类变量与类方法。正如上所说堆犹如一本书的正文,但是此书正文四杂乱无序,所以需要一小页的目录(栈)来帮助查找,而静态区就像此书的序言,不管内容多乱,但是序言总是在最前面的,很容易就翻到的。
3. 静态变量(类变量)static修饰的静态方法会随着类的定义而被分配和装载入内存中,编译器只为整个类创建了一个静态变量的副本,也就是只分配一个内存空间,虽然可能有多个实例,但这些实例共享该内存,特别值得注意的是,任何一个对象对静态数据成员的修改,都会影响其它对象。
也就是说,被static修饰的成员变量,就变成了静态变量(类变量),只会加载一次。只会加载一次说明类变量是共享的唯一的。
举个栗子,你在大学寝室玩电脑,这时你室友也看到了,也想玩,如果电脑(成员变量)没被static修饰,你室友也会去赋值一台属于自己的电脑。但是如果电脑(成员变量)被static修饰了,就变成了共享的电脑(即变成了类变量,也叫静态变量),你的电脑不再是你的了,而是属于全寝室(类),你室友对电脑的操作也会影响到你,如你室友给电脑屏幕上写个正字,那轮到你玩的时候,该电脑屏幕上也会有个正字。
再说一次,普通变量从属于对象,即每个人都有自己的电脑,类变量从属于类,即该类(寝室)的对象都只能玩同一台电脑。
4. 静态方法(类方法)
被static修饰的成员方法,就变成了静态方法(类方法),即从属于类的方法,因为不从属于对象,可以不创建对象即可调用。
举个栗子,有个水池类,有加水的水管(方法),如果没有被static修饰的加水方法,是要先new一个水池类的对象,再通过对象调用,相当于每个水池都有自己的水管,而被static修饰的方法,则相当于所有水池类里的对象都共用一条水管,不用问用哪个水池的水管(不必通过对象调用,)。静态方法
补充一点,我们知道,两个非静态方法在同一类下是可以直接引用的(都在一个类空间里,容易找)。
而即便处于同一类体的方法,静态方法是不能直接引用非静态方法的,正如前面所说,静态区相当于一块固定的空间,从固定的空间去无序的空间找是很难找到的(敌暗我明)。而非静态里却可以直接调用静态方法,因为从无序的空间去有序的空间找是容易的(敌明我暗)。
敌暗我明、敌明我暗
5. 通过4个例子深入清楚知道静态非静态之间的区别
重要的事再说一遍:静态变量与静态方法之所以可以直接调用是因为它们从属于类,不从属于对象,故又称类变量与类方法,再以四张图简单对比静态与非静态的区别。
5.1非静态变量,非静态方法,各有各的车,各开各的车。非静态变量,非静态方法,各有各的车,各开各的车。
5.2静态变量,非静态方法,大家开唯一的一辆车。静态变量,非静态方法,大家开唯一的一辆车。
5.3静态变量,静态方法,不用通过对象(人)就能开,上帝(灵魂)开大家唯一的一辆车.静态变量,静态方法,不用通过对象(人)就能开,上帝(灵魂)开大家唯一的一辆车.
5.4非静态变量,静态方法,上帝可以开每个人的车,但必须告诉上帝开哪辆(参数)。非静态变量,静态方法,上帝可以开每个人的车,但必须告诉上帝开哪辆(参数)。