今天在和同事讨论的时候谈到了关于static的问题,正巧自己有一些忘记了,就特来学习一番。
首先,Java中的static关键字主要用于内存管理。static 关键字属于类,而不是类的示例。(敲黑板)。在程序中任何变量或者代码都是编译时分配代码的,而静态修饰的就会一直存在内存中,直到程序退出。也就是说,在我们的日常使用中,如果在某个类中要使用其他类,那么只能先把待使用的类进行实例化,然后通过对象引用它,但是,如果有static修饰的成员,那么我们是可以 类名.成员名 来直接进行访问的,所以这里也就说明了上面的那句话:static 关键字属于类,而不是类的示例。
static 关键字可以修饰的如下:
- 变量
- 方法
- 块(也就是局部代码块)
- 内部类
Java 修饰静态变量
被static修饰的变量成为静态变量,被JVM加载时只被加载一次到内存中,所以节省了内存(当然有并发情况就要考虑的复杂了)
比如,我们现在有个people类,如果现在有100个人,那么我们就要初始化100个实例,如果这个类中含有如下字段
private static String type = "学生";
那么对是学生的人群,这个字段只需要初始化一次就够,其他人的引用都指向同一个内存,节约了内存。
Java 修饰静态方法
被static修饰的方法称为静态方法,其中,静态方法属于类而不是属于对象(继续敲黑板),所以无需实例化就可以调用静态方法。因此不能使用 this 和 supper 进行调用,这里要注意下,而且static 独立于示例,所以是不能修饰 抽象的 abstract 的。
Java 修饰代码块
- 用于初始化静态数据成员。
- 在类加载时,在main方法前执行。
- 可以有多个静态代码块。在存在多个时,JVMM会按照它们出现的先后顺序执行,每个代码块只会执行一次
public class StaticTest {
static {
System.out.println("这是一个static 块 ------- 1");
}
static {
System.out.println("这是一个static 块 ------- 2");
}
public static void main(String[] args) {
System.out.println("这是一个main方法");
}
}
输出是:
这是一个static 块 ------- 1
这是一个static 块 ------- 2
这是一个main方法
我们在使用static的时候,会经常搭配final一起使用,static final 修饰变量,表示不可修改;修饰方法,表示不可被覆盖。
但是,我们在使用的时候,不可修改指的是实例常量,实例本身是不可以改变了,比如我们把这个实例变成 null,这个时候就会编译出错。
但是我们可以改变实例对象中的属性的,比如
static 修饰内部类
在一个类中创建另一个类,叫做内部类,用static 修饰内部类,叫做静态内部类,当然,内部类也可以是非静态的。
使用场景:创建内部类时,不想创建一次内部类就需要创建一次外围类。内部类与外部类有很强联系,增加可读性。
我们知道,非静态内部类在编译完成后,会保存着一个指向外部类的引用,But ,静态内部类是没有的,它的创建是不需要依赖外部类的,但是它不能使用任何外围类的非静态成员变量和方法。
静态变量、静态块和静态方法的区别
- 静态代码块是自动执行的
- 静态方法是被调用才执行的
- 静态代码块和静态变量的执行顺序也是按顺序执行的。比如
private static int num = 10; static { num = 20; } public static void main(String[] args) { System.out.println(num); }
输出
20
当然,如果是下面这样的话,其实
System.out.println(num); 输出的还是 private static int num = 10;定义的内容
private static int num = 10; static { int num = 20;//变成了局部变量 } public static void main(String[] args) { System.out.println(num); }