static 关键字
在Java中,被static声明过的成员变量称为静态成员变量,也称为类变量。如果一个成员使用了static关键字修饰,那么这个成员就不在属于对象了,而是属于类,在这个类中的所有对象实例所共享,可以节省很多内存空间;
也可以用一句话来总结,就是方便在没有创建对象的情况下来进行调用,也就是说,被static所修饰过的成员变量或者成员方法,不需要去new一个实例对象,然后再进行调用,而是可以直接通过 类名就可以去访问,举个例子:
public class student{
//定义一个静态变量
static String school;
}
然后直接通过类名去进行访问
Student.school = "XXX";
这个就是static的关键用法,只要这个类被加载,那么这个静态变量也会跟着一起加载,而且这个静态成员被该类的所有对象所共享;这里可以得出以下结论:
- 静态变量被所有对象共享,在内存中只有一个副本,在类初次加载的时候才会初始化
- 非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响
- static成员变量初始化顺序按照定义的顺序来进行初始化
啥时候需要用到static关键字呢?有什么好处?
就拿上面的例子来说,共性(共享)的属性使用静态,特性使用非静态
class Student {
//因为同一个学校的学生类,school属性是相同的,所以用静态修饰,可以节省内存
static String school;
String name;
int age ;
}
static的注意事项:
- 可以调用静态的成员变量,成员方法
- 不能调用非静态的成员变量,成员方法
- 只能在静态方法中调用静态的成员
如图所示,还是上面的例子:
name这个属性我们没有用static来修饰,所以是属于对象的,要对象实例化之后才可以访问,继续如下所示
对象实例化之后是可以正常访问的;
static常见笔试面试题
1、下面这段代码的输出结果是什么?
public class Student extends Person{
static{
System.out.println("Student static");
}
public Student(){
System.out.println("Student constructor");
}
public static void main(String[] args) {
new Student();
}
}
class Person{
static{
System.out.println("Person static");
}
public Person(){
System.out.println("Person constructor");
}
}
输出结果:
Person static
Student static
Person constructor
Student constructor
这是为什么呢,让我们来看看原因:
- 首先执行这块代码的时候,一般是先找程序的入口,也就是main方法,但是在执行main方法之前,首先要加载Student类
- 加载Student类的时候,发现这个类继承Person类,所以就会优先父类
- 加载Person类,发现Person类有static模块,会优先加载,所以这里输出:Person static
- 加载完Person类之后加载Student类,也发现有static模块,也会优先加载,接着输出:Student static
- 两个类都加载完之后,执行主方法里面的new Student(),调用子类构造器之前会先调用父类构造器,这里输出:Person constructor
- 最后调用子类的构造器,最后输出:Student constructor
总结:
- 静态内容总是优先于非静态,所以静态代码块比构造方法优先执行
- static块可以出现类中的任何地方,并且执行是按照static块的顺序执行的。