本次讲解static,主要涉及以下三点
1.static修饰的静态变量
2.static修饰的静态方法和工具类
3.static的注意事项
1.static修饰的静态变量:我们首先了解什么是static,static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量。被static修饰的成员变量,叫做静态变量,特点是被该类的所有对象共享 ,调用方式有:1.类名调用,2.对象名调用;被static修饰的成员方法,叫做静态方法。
来看此图中的代码,在左边的类中,teachername被定义成static String,这就代表此时这个teachername已经是一个静态变量了,在右边的测试类中,我们就可以通过类名.teachername来进行修改他的值,当然也可以用s1.teachername,如果用了s1.teachername来修改的话,在进行s2.show()的时候,teachername还是跟s1是一样的。但是不推荐用s1,s2来修改静态变量,这就是静态变量的特点。
接下来从内存方向来解释这个原理。
首先这个程序遇到main,要把整个程序放入栈中,接下来继续往后执行;第二句Student.teachername="阿伟老师"这句话,就是在堆内存中,开辟一片区域,叫做静态区,也就是静态存储的位置,存入我们的teachername;紧接着继续往后,看到了new,所以就是在堆中开辟一个对象空间,此时s1就代表着对应空间的地址,0x001;然后在后边两句话就是把对应的数进行修改,在s1.show的时候再次把方法加载进栈,然后再执行,当读取到name和age的时候,JVM会数组内和地址0X0011去找堆中的对象,在执行到teachername的时候,JVM会自动识别出他是被static修饰的静态变量,会直接去堆内存中的静态存储位置(静态区)读取共享的静态数据。
总结:被static修饰的成员变量的特点:被该类所有对象共享;不属于对象,属于类;随着类的加载而加载,优先于对象存在。
2.static修饰的静态方法:特点:多用在测试类和工具类中;在JavaBean类中很少会用;调用方式:类名调用(推荐) ,对象名调用。
先来讲一下什么是工具类:工具类就是帮助我们做一些事情的,但是不描述任何事物的类。
工具类需要的注意事项:
1.类名见名知意
2.私有化构造方法
3.方法定义为静态
针对工具类为什么要私有化构造方法并配合static,原因如下:
1.方便调用(无需创建对象) 方法加上 static 后,外部可以直接通过类名调用(例如 ArrayUtil.printArr(arr)),不需要先 new ArrayUtil()。这对于不依赖对象状态的通用工具逻辑来说最高效
2.节省内存(防止实例化) 工具类只提供通用的计算逻辑,类内部没有任何需要用 new 储存在堆内存中的成员变量。如果外界随意 new ArrayUtil(),会白白浪费堆内存空间。
3.强制规范(私有构造) 把构造方法声明为 private ArrayUtil(){},外界就无法通过 new 来创建该类的对象 。这是一种面向对象设计的防错机制,强制使用者只能通过 类名.静态方法 的形式来使用它。
3.static的注意事项:
1.静态方法中,只能访问静态变量和静态方法:在静态方法中直接访问非静态变量,就像试图在房子还没盖好(没 new 对象)时去使用房里的家具。JVM 无法预知你指的到底属于哪个具体的堆对象,因此语法上直接禁止。
2.非静态方法和可以访问所有:此时,早到的静态资源(类加载时已就位)和后到的非静态资源(new 对象时已就位)在内存里全都在场。既然大家都在,非静态方法自然可以随意访问所有资源。
3.静态方法中没用有this关键字:静态方法属于类本身,推荐直接用 类名.静态方法() 调用,完全可以脱离对象独立运行。既然静态方法在执行时可能压根没有关联任何对象,那么代表"当前对象"的 this 引用在静态方法的栈帧里就没有任何存在的依据。通俗来讲,这个就是属于整个类的,他不单独属于任何变量。