代码初始化块是类的成员之一,每次类的创建会隐式的调用它。本质上是一个代码块,或方法体。
初始化块分为静态初始化块和普通初始化块。其好处是减少多个构造器内重用的代码;
特点:
一:
public class TestInit1 {
public static void main(String[] args) {
System.out.println((int)(Math.random()*40+1));
System.out.println(InitDemo1.a);//加载类
new InitDemo1();
}
}
class InitDemo1{
static int a =100;
{
System.out.println("我是普通初始化块");
}
static{
System.out.println("我是静态初始化块");
}
}
普通初始化块:创建对象时隐式调用
静态初始化块:类加载时隐式调用
二:
public class TestInit2 {
public static void main(String[] args) {
new InitDemo2();
new InitDemo2();
new InitDemo2();
new InitDemo2();
new InitDemo2();
}
}
class InitDemo2{
static int a =100;
{
System.out.println("我是普通初始化块");
}
static{
System.out.println("我是静态初始化块");
}
}
静态初始化块只调用一次(类加载时),而普通初始化块可以调用多次,随着对象的创建而加载
三:
public class TestInit3 {
public static void main(String[] args) {
new InitDemo3();//加载+创建对象
}
}
class InitDemo3{
{
System.out.println("我是普通初始化块1");
}
static{
System.out.println("我是静态初始化块1");
}
{
System.out.println("我是普通初始化块2");
}
{
System.out.println("我是普通初始化块3");
}
static{
System.out.println("我是静态初始化块2");
}
static{
System.out.println("我是静态初始化块3");
}
}
一个类中可以有多个静态初始化块和多个普通初始化块;静态初始化块的执行要早于普通初始化块;同一个类型的初始化块的执行顺序取决于定义的先后顺序!
四:
public class TestInit4 {
public static void main(String[] args) {
InitDemo4 id = new InitDemo4();
}
}
class InitDemo4{
public InitDemo4(){
System.out.println("我是构造器");
}
String a=msg("普通属性初始化1");
public static String msg(String info){
System.out.println(info);
return info;
}
static{
System.out.println("静态初始化块2");
}
static String b=msg("静态属性初始化1");
{
System.out.println("我是普通初始化块1");
}
String c=msg("普通属性初始化2");
{
System.out.println("我是普通初始化块2");
}
static String d=msg("静态属性初始化2");
static{
System.out.println("静态初始化块1");
}
}
在一个类中如果有多个不同的初始化块,初始化属性,构造器,
执行顺序是:静态初始化块|静态属性初始化 > 普通初始化块|普通属性初始化 > 构造器
五:
public class TestInit5 {
public static void main(String[] args) {
InitDemo5 id = new InitDemo5();
}
}
class Grand {
public Grand() {
System.out.println("我是爷爷类的构造器");
}
String a = fun("爷爷类的普通属性初始化");
public static String fun(String info) {
System.out.println(info);
return info;
}
static {
System.out.println("爷爷类的静态代码块");
}
{
System.out.println("爷爷类的普通代码块");
}
static String d = fun("爷爷类的静态属性初始化");
}
class Father extends Grand {
public Father() {
System.out.println("我是爷爷类的构造器");
System.out.println("我是父类的构造器");
}
String a = method("父类的普通属性初始化");
public static String method(String info) {
System.out.println(info);
return info;
}
static {
System.out.println("父类的静态代码块");
}
{
System.out.println("父类的普通代码块");
}
static String d = method("父类的静态属性初始化");
}
class InitDemo5 extends Father {
public InitDemo5() {
System.out.println("我是子类的构造器");
}
String a = msg("子类的普通属性初始化");
public static String msg(String info) {
System.out.println(info);
return info;
}
static {
System.out.println("子类的静态代码块");
}
{
System.out.println("子类的普通代码块");
}
static String d = msg("子类的静态属性初始化");
}
在父子类中,执行顺序是:
爷爷类的静态初始化块|静态属性初始化>
父类静态初始化块|静态属性初始化>
子类静态初始化块|静态属性初始化>
爷爷类普通初始化块|普通属性初始化>构造器>父类普通初始化块|普通属性初始化>构造器>
子类普通初始化块|普通属性初始化>构造器
六:静态初始化块中遵循静态成员的特点,只能直接访问静态成员!也就是在静态初始化块只能修改静态成员。
题->
class A{
final int x;
final static int y;
public A(){
y=10;
x=100;//×
}
{
x=100;
y=10;//×
}
}
普通初始化块只能初始化普通的变量,普通的构造器也只能初始化普通的变量。