域名建设网站,网站代理最快最干净,如何免费建立个人网站,今天重大新闻文章目录1、初识初始化块2、实例初始化块和构造器3、类初始化块1、初识初始化块
Java 使用构造器来对单个对象进行初始化操作#xff0c;使用构造器先完成对整个 Java 对象的状态初始化#xff0c;然后将 Java 对象返回给程序#xff0c;从而让该 Java 对象的信息更加完整。…
文章目录1、初识初始化块2、实例初始化块和构造器3、类初始化块1、初识初始化块
Java 使用构造器来对单个对象进行初始化操作使用构造器先完成对整个 Java 对象的状态初始化然后将 Java 对象返回给程序从而让该 Java 对象的信息更加完整。
与构造器作用非常类似的是初始化块它也可以对 Java 对象进行初始化操作。
初始化块定义的格式
[修饰符]{// 代码
}代码 public class Demo02 {// 实例初始化块{System.out.println(实例初始化块执行了...);}// 类初始化块static {System.out.println(类初始化块执行了...);}// 构造器public Demo02() {System.out.println(无参构造器执行了...);}public static void main(String[] args) {new Demo02();System.out.println(------------------);new Demo02();}
}结果 类初始化块执行了...
实例初始化块执行了...
无参构造器执行了...
------------------
实例初始化块执行了...
无参构造器执行了...说明 一个类里可以有多个初始化块相同类型的初始化块之间有顺序先定义的先执行后定义的后执行。初始化块如果有修饰符的话只能是 static。使用 static 修饰的初始化块称为类初始化块静态初始化块。没有 static 修饰的初始化块称为实例初始化块非静态初始化块初始化块里的代码可以包含任何可执行性语句包括定义局部变量、调用其他对象的方法、以及使用分支、循环语句等。初始化块虽然是 Java 类的一种成员但它没有名字、标识因此无法通过类、对象来调用初始化块。实例初始化块只在创建 Java 对象时隐式执行而且在构造器之前自动执行。类初始化块则在类初始化阶段自动执行。
注
虽然一个类里允许定义 2 个实例初始化块但这没有任何意义。
因为实例初始化块是在创建对象时隐式调用的而且它们总是全部执行因此完全可以把多个实例初始化块合并成一个实例初始化块让程序简洁、可读性强。
2、实例初始化块和构造器
实例初始化块、声明实例变量时指定的默认值都可认为是对象初始化代码它们的执行顺序与源程序中的排列顺序相同。
public class Demo01 {// 声明实例变量的默认值在前public int a 10;// 实例初始化块在后{a 20;}public Demo01() {}public static void main(String[] args) {Demo01 demo01 new Demo01();System.out.println(demo01.a); // 20 }
}public class Demo01 {// 实例初始化块在前{a 20;}// 声明实例变量的默认值在后public int a 10;public Demo01() {}public static void main(String[] args) {Demo01 demo01 new Demo01();System.out.println(demo01.a); // 10}
}说明 当 java 创建一个对象时系统先为该对象的所有实例变量分配内存前提是该类已经被加载过了接着程序开始对这些实例变量执行初始化。
执行初始化的顺序是先执行实例初始化块 或 声明实例变量时指定的默认值执行顺序与它们在源码中的排列顺序相同再执行构造器中指定的初始值。 与构造器不同的 实例初始化块是一段固定执行的代码无法接收任何参数因此实例初始块对一个类中的所有对象执行的初始化操作是相同的。 如何使用 如果有一段初始化处理代码中对所有对象完全相同且无须接收任何参数就可以把这段实例初始化代码提取到实例初始化块中。 对实例初始化块的分析 实力初始化块是一个假象在编译之后的字节码文件中实例初始化块会消失——实例初始化块会被 “还原” 到每个构造器中且位于构造器所有代码的前面。
Demo02.java
public class Demo02 {// 实例初始化块{System.out.println(实例初始化块执行了...);}// 类初始化块static {System.out.println(类初始化块执行了...);}// 构造器public Demo02() {System.out.println(无参构造器执行了...);}public static void main(String[] args) {new Demo02();System.out.println(------------------);new Demo02();}
}编译之后的字节码文件 Demo02.class
public class Demo02 {public Demo02() {System.out.println(实例初始化块执行了...);System.out.println(无参构造器执行了...);}public static void main(String[] args) {new Demo02();System.out.println(------------------);new Demo02();}static {System.out.println(类初始化块执行了...);}
}与构造器类似创建一个对象时不仅会执行该类的实例初始化块和构造器而且系统会先执行其父类中的实例初始化块如果有和构造器一直追溯到祖宗类 Object 类先执行 Object 类的实例初始化块如果有、构造器最后才执行该类的实例初始化块如果有和构造器返回该类的对象。 代码 class Person {{System.out.println(Person--实例初始化块);}public Person() {System.out.println(Person--构造器);}
}class Student extends Person {{System.out.println(Student--实例初始化块);}public Student() {System.out.println(Student--构造器);}public static void main(String[] args) {new Student();}
}结果 Person--实例初始化块
Person--构造器
Student--实例初始化块
Student--构造器如果希望类加载后对整个类类变量进行某些初始化操作就需要使用 static 关键字来修饰初始化块。
3、类初始化块
实例初始化块负责对对象执行初始化类初始化块负责对类初始化。
系统在类初始化阶段执行类初始化块而不是创建对象时执行因此类初始化块总是比实例初始化块先执行。
当 JVM 第一次主动使用某个类时系统会在类准备阶段为该类的所有类变量分配内存在初始化阶段负责初始化类变量。
类初始化块、声明类变量时指定的默认值都可认为是类初始化代码它们的执行顺序与源程序中的排列顺序相同。
public class Demo01 {public static String name java;static {name JAVA;}public static void main(String[] args) {System.out.println(Demo01.name); // JAVA}
}public class Demo01 {static {name JAVA;}public static String name java;public static void main(String[] args) {System.out.println(Demo01.name); // java}
}注
类初始化块静态初始化块属于类的静态成员同样遵循静态成员不能访问非静态成员的规则。
因此类初始化块不能访问非静态成员实例变量、实例方法
与实例初始化块类似的是系统在类初始化阶段执行类初始化块时不仅会执行本类的类初始化块而且还会一直上溯到 Object 类的类初始化块如果有先执行 Object 的类初始化块如果有然后执行其父类的类初始化块 ……最后在执行本类的类初始化块。
只有当类初始化完成之后才可以在系统中使用这个类类变量、类方法、创建对象
Java 系统加载并初始化某个类时总是保证该类的所有父类直接父类或间接父类全部加载并初始化。 Root public class Root {static {System.out.println(Root--静态初始化块);}{System.out.println(Root--实例初始化块);}public Root() {System.out.println(Root--无参构造器);}
}Mid public class Mid extends Root{static {System.out.println(Mid--静态初始化块);}{System.out.println(Mid--实例初始化块);}public Mid() {System.out.println(Mid--无参构造器);}public Mid(String msg) {// 调用同一个类中的无参构造器this();System.out.println(Mid--有参构造器参数 msg);}
}Leaf public class Leaf extends Mid{static {System.out.println(Leaf--静态初始化块);}{System.out.println(Leaf--实例初始化块);}public Leaf() {super(java);System.out.println(Leaf--无参构造器);}
}Application public class Application {public static void main(String[] args) {new Leaf();System.out.println(-------------------);new Leaf();}
}结果 Root--静态初始化块
Mid--静态初始化块
Leaf--静态初始化块
Root--实例初始化块
Root--无参构造器
Mid--实例初始化块
Mid--无参构造器
Mid--有参构造器参数java
Leaf--实例初始化块
Leaf--无参构造器
-------------------
Root--实例初始化块
Root--无参构造器
Mid--实例初始化块
Mid--无参构造器
Mid--有参构造器参数java
Leaf--实例初始化块
Leaf--无参构造器