今天在和同事讨论的时候谈到了关于static的问题,正巧自己有一些忘记了,就特来学习一番。
首先,Java中的static关键字主要用于内存管理。static 关键字属于类,而不是类的示例。(敲黑板)。在程序中任何变量或者代码都是编译时分配代码的,而静态修饰的就会一直存在内存中,直到程序退出。也就是说,在我们的日常使用中,如果在某个类中要使用其他类,那么只能先把待使用的类进行实例化,然后通过对象引用它,但是,如果有static修饰的成员,那么我们是可以 类名.成员名 来直接进行访问的,所以这里也就说明了上面的那句话:static 关键字属于类,而不是类的示例。
static 关键字可以修饰的如下:
被static修饰的变量成为静态变量,被JVM加载时只被加载一次到内存中,所以节省了内存(当然有并发情况就要考虑的复杂了)
比如,我们现在有个people类,如果现在有100个人,那么我们就要初始化100个实例,如果这个类中含有如下字段
private static String type = "学生";
那么对是学生的人群,这个字段只需要初始化一次就够,其他人的引用都指向同一个内存,节约了内存。
被static修饰的方法称为静态方法,其中,静态方法属于类而不是属于对象(继续敲黑板),所以无需实例化就可以调用静态方法。因此不能使用 this 和 supper 进行调用,这里要注意下,而且static 独立于示例,所以是不能修饰 抽象的 abstract 的。
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 修饰内部类,叫做静态内部类,当然,内部类也可以是非静态的。
使用场景:创建内部类时,不想创建一次内部类就需要创建一次外围类。内部类与外部类有很强联系,增加可读性。
我们知道,非静态内部类在编译完成后,会保存着一个指向外部类的引用,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);
}