1. 静态代码块
静态代码块:定义在类中方法外,使用static修饰
①可以为类变量(静态变量)初始化
②静态代码块在第一次使用这个类之前执行,即在类初始化时执行,且只执行一次
③若有多个静态代码块,那么按照定义的先后顺序依次执行
④在静态代码块中不能访问非静态成员(属性、方法、内部类)
⑤在静态代码块中不能使用this和super关键字
⑥静态代码块的执行优先于main方法、非静态代码块和构造方法的执行
⑦父类静态代码块的执行优先于子类静态代码块执行
代码示例:
public class StaticBlockTest {
public static void main(String[] args) {
MyClass.show();
MyClass.show();
MyClass.show();
}
static {
System.out.println("StaticBlockTest类静态代码块");
}
}
class MyClass {
static {
System.out.println("MyClass类静态代码块1");
}
public static void show() {
System.out.println("MyClass类静态方法");
}
static {
System.out.println("MyClass类静态代码块2");
}
}
运行结果:
StaticBlockTest类静态代码块
MyClass类静态代码块1
MyClass类静态代码块2
MyClass类静态方法
MyClass类静态方法
MyClass类静态方法
2. 类初始化
类初始化即执行类初始化方法:<clinit>()
类初始化方法,一个类只有一个。它也是由编译器编译生成的,由两部分代码组成:
①静态变量的显式赋值代码
②静态代码块的代码
其中①和②是按定义的先后顺序依次执行的
代码示例:
public class InitTest {
public static void main(String[] args) {
MyClass my = new MyClass();
}
}
class MyClass {
static {
System.out.println("MyClass类静态代码块1");
}
private static String str = assingn();
public static void show() {
System.out.println("MyClass类静态方法");
}
private static String assingn() {
System.out.println("assign()方法为静态变量显式赋值");
return "java";
}
static {
System.out.println("MyClass类静态代码块2");
}
}
运行结果:
MyClass类静态代码块1
assign()方法为静态变量显式赋值
MyClass类静态代码块2
3. 子类初始化
一个类初始化时会先检查它的父类是否初始化,如果父类没有初始化,那么会先初始化父类
(1)父类的初始化
-
父类的静态变量的显式赋值
-
父类的静态代码块
(2)子类的初始化
-
父类的静态变量的显式赋值
-
父类的静态代码块
代码示例:
public class InitTest2 {
public static void main(String[] args) {
/*Father f = new Father();
System.out.println("--------分隔线---------");*/
Son s = new Son();
}
}
class Father{
private static String info = assign();
static{
System.out.println("父类的静态代码块");
}
//静态方法不能被重写
public static String assign(){
System.out.println("父类assign()方法");
return "Father";
}
}
class Son extends Father{
private static String info = assign();
static{
System.out.println("子类的静态代码块");
}
public static String assign(){
System.out.println("子类assign()方法");
return "Son";
}
}
运行结果:
父类assign()方法
父类的静态代码块
子类assign()方法
子类的静态代码块
4. 类初始化和实例初始化结合
先执行类初始化,后执行实例初始化
代码示例:
public class InitTest3 {
public static void main(String[] args) {
Demo d = new Demo();
}
}
class Demo{
{
System.out.println("非静态代码块1");
}
static{
System.out.println("静态代码块1");
}
public Demo(){
System.out.println("无参构造");
}
private static String info = assignInfo();
private String msg = assignMsg();
static{
System.out.println("静态代码块2");
}
{
System.out.println("非静态代码块2");
}
public static String assignInfo(){
System.out.println("assignInfo()方法");
return "hello";
}
public String assignMsg(){
System.out.println("assignMsg()方法");
return "msg";
}
}
运行结果:
静态代码块1
assignInfo()方法
静态代码块2
非静态代码块1
assignMsg()方法
非静态代码块2
无参构造
5. 子类初始化和子类实例初始化结合
执行顺序:①父类的类初始化 => ②子类的类初始化 => ③父类的实例初始化方法 => ④子类的实例初始化方法
public class InitTest4 {
public static void main(String[] args) {
//Father f = new Father();
Son s = new Son();
}
}
class Father {
{
System.out.println("父类非静态代码块1");
}
static {
System.out.println("父类静态代码块1");
}
private static String info = assignInfo();
private String msg = assignMsg();
public Father() {
System.out.println("父类无参构造");
}
static {
System.out.println("父类静态代码块2");
}
{
System.out.println("父类非静态代码块2");
}
public static String assignInfo() {
System.out.println("父类assignInfo()方法");
return "hello";
}
public String assignMsg() {
System.out.println("父类assignMsg()方法");
return "msg";
}
}
class Son extends Father {
{
System.out.println("子类非静态代码块1");
}
static {
System.out.println("子类静态代码块1");
}
private static String info = assignInfo();
private String msg = assignMsg();
public Son() {
System.out.println("子类无参构造");
}
static {
System.out.println("子类静态代码块2");
}
{
System.out.println("子类非静态代码块2");
}
public static String assignInfo() {
System.out.println("子类assignInfo()方法");
return "hello";
}
public String assignMsg() {
System.out.println("子类assignMsg()方法");
return "msg";
}
}
父类静态代码块1
父类assignInfo()方法
父类静态代码块2
子类静态代码块1
子类assignInfo()方法
子类静态代码块2
父类非静态代码块1
子类assignMsg()方法
父类非静态代码块2
父类无参构造
子类非静态代码块1
子类assignMsg()方法
子类非静态代码块2
子类无参构造