目录
修饰成员变量
private String gender;
public static String teacherName;
定义static成员变量
直接用类名调用
//因为这个成员变量是被该类所有对象共享的,所以最好用类名调用(不是属于某个对象的)
static内存
在执行这条语句时,并没有创建对象,静态变量优先于对象出现,随着类的加载而加载
因为show方法的调用者是s1,就会通过s1去找name age再去找静态区里的teachername
静态区的变量是对象共享的,在内存中只有一份,谁要用谁去拿;非静态的变量是每一个对象独有的
修饰成员方法
static注意事项
代码方面理解
非静态方法有一个隐藏的this(在形参的最前面,但是不可以自己赋值,方法在调用时又虚拟机把调用者的地址值赋值给它)
每个类都可以创建实例,然后由实例调用对象的方法,所以this指向当前调用者的地址,静态方法是在静态区,由类名直接调用,而不是具体的实例,所以没有this
this指的是s1调用show1
this.show2指的是show1的调用者s1再调用show2
java为什么要这么设计呢?
非静态的东西往往和对象相关,必须要有this
静态的东西是共享的,与某一个对象无关,没有this
静态方法只能访问静态,反过来理解就是静态方法中不能访问非静态的东西(成员变量和成员方法)
而且静态方法没有this,所以根本不知道是访问哪个对象的
也不可以调用成员方法
非静态的方法可以访问所有:因为静态也可以用对象调用,访问到共享数据
内存方面理解
静态和非静态在内存中出现的时机不同
非静态的成员变量又称做实例变量(实例==对象)
当静态加载到内存中去,如果没有创建对象,就没有非静态的数据,静态的东西可以互相调用,非静态的东西和对象有关,只要没有创建对象,非静态的东西就不会出现在内存中,所以静态无法调用非静态
JDK7以前静态和非静态都在方法区
JDK7以后静态的被单独抽取出来放到堆当中(静态区)
静态方法只能访问静态
main先进栈,执行,用到了Student类,将Student的字节码文件加载到方法区(包括成员变量和成员方法),JDK7以后,静态变量移动到了堆当中(静态区),Student类中有一个静态的变量teacherName,就会出现在静态区中,默认初始化值为null,赋值,null被"阿玮老师"替代
第二行调用了静态方法method,找到方法区中的method字节码文件,把method加载到栈中,在方法里要获取两个变量(name和teacherName),而当前的方法是由Student这个类名调用的,要到堆中的Student静态区里找name和teacherName,显然找不到name(name不是静态的,不会出现在静态区中)
因此静态方法不能调用非静态的成员变量
实例变量和对象有关,现在还没有创建对象,当然调用不了对象里的实例变量
静态方法不能调用非静态
假设可以调用,普通的成员方法在调用时必须有一个调用者,这个调用者就是创建的对象,而此时没有创建对象,自然没有调用者,也没法调用普通的成员方法
非静态可以访问所有
通过s1找到teacherName可行,所以非静态的当然可以访问静态的
s1也可以找到静态方法method,加载到内存中
拓展
单例设计模式里的static并不是核心亮点,多线程里的才是核心亮点