static变量
类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它,取到的都是相同的值,同样任何一个该类的对象去修改它,修改的也是同一个变量。
(1)static类变量所有对象共享
(2)static类变量在类加载时生成
类变量是随着类的加载而创建,所以即使没有创建对象实例也可以通过类名点类变量名进行访问。
static方法
当方法中不涉及到任何和对象相关的成员,则可以将方法设计成静态方法,提高开发效率。在实际开发中,往往会将一些通用的方法,设计成静态的方法,这样我们不需要创建对象就可以使用了,比如打印一组数组,冒泡排序,完成某个计算任务等…
(1)静态方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区,静态方法中无this参数,普通方法中有this参数
(2)静态方法可以通过类名调用,也可以通过对象名调用
(3)普通方法和对象有关,需要通过对象名调用,比如对象名.方法名(参数),不能通过类名调用
(4)静态方法中不可以使用对象有关的关键词,比如this和super。普通方法可以。
(5)静态方法只能访问静态变量和静态方法。
静态方法,只能访问静态的成员。非静态的方法,可以访问静态成员和非静态成员。
static main()方法
main方法的形式:
public static void main(String[] args){}
main方法由java虚拟机(jvm)调用。java虚拟机需要调用main方法,所以该方法的访问权限必须是public。java虚拟机在执行main()方法不必创建对象,所以该方法必须是static。该方法接收String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数。
在 main()方法中,我们可以直接调用 main 方法所在类的静态方法或静态属性。但是,不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员。
static代码块
代码块又称为初始化块,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。但和方法不同,没有方法名,没有返回值,没有参数,只有方法体,而且不用通过对象或类显示调用,而是加载类时或创建对象时隐式调用。
(1)修饰符可选,只能写static,使用static修饰的叫静态代码块,没有static修饰的叫普通代码块或者非静态代码块。
(2)代码块相当于一种对构造器的补充机制,可以做初始化的操作。如果当多个重写的构造器中都有重复语句时,可以抽取到初始化块中,提高代码的复用性。
(3) 代码的执行顺序优先于构造器,静态代码块随着类的加载而执行,并且只会执行一次,而普通代码块每次创建一个对象都会执行一次。
(4)静态代码块和静态方法一样只能访问静态变量和静态方法。
静态代码块类加载时执行且只执行一次。普通代码块创建对象时执行,创建一次,执行一次。
创建一个类时调用顺序:(静态代码块/静态属性初始化) > (普通代码块/普通属性初始化) > 构造方法
创建一个子类对象时,他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:
①父类的静态代码块和静态属性(优先级一样,按顺序执行)
②子类的静态代码块和静态属性(优先级一样,按顺序执行)
③父类的普通代码块和普通属性(优先级一样,按顺序执行)
④父类的构造方法
⑤子类的普通代码块和普通属性(优先级一样,按顺序执行)
⑥子类的构造方法
样例代码:
package com.liuranli;
public class test {
public static void main(String[] args) {
new Test2();
}
}
class Sample {
Sample(String s) {
System.out.println(s);
}
Sample() {
System.out.println("Sample 默认构造函数被调用");
}
}
class Test2 extends Sample {
Sample sample = new Sample("sam1成员初始化");
static Sample sample2 = new Sample("静态成员sam初始化");
static {
System.out.println("static块执行");
if (sample2 == null) System.out.println("sample is null");
}
Test2() {
super();
System.out.println("Test 默认构造函数被调用");
}
}
样例输出:
静态成员sam初始化
static块执行
Sample 默认构造函数被调用
sam1成员初始化
Test 默认构造函数被调用