问题背景:
想了解Java类非静态成员变量以及静态成员变量的初始化过程。在代码块中使用System.out.println输出语句,输出成员变量的值,但是出现非法引用的提示。具体代码如下。
具体代码:
class A {
public A() {
System.out.println("父类A的构造方法");
System.out.println("静态成员变量 = " + staticStr + ", 非静态成员变量 = " + str);
}
{
//System.out.println(str); //错误: 非法前向引用
str = "123";
System.out.println("父类A的构造代码块0");
}
static {
staticStr = "1234";
//System.out.println(staticStr);
System.out.println("父类A的静态代码块0");
}
private static String staticStr = iniStaticStr();
static {
System.out.println(staticStr);
System.out.println("父类A的静态代码块");
}
private String str = iniStr();
{
System.out.println(str);
System.out.println("父类A的构造代码块");
}
private static String iniStaticStr() {
System.out.println("staticStr = " + staticStr);
System.out.println("静态成员变量显示初始化");
return "iniStaticStr";
}
private String iniStr() {
System.out.println("str = " + str);
System.out.println("非静态成员变量显示初始化");
return "iniStr";
}
{
//System.out.println(str);//错误: 非法前向引用
System.out.println("父类A的构造代码块1");
}
static {
System.out.println("父类A的静态代码块1");
}
}
class B extends A {
static {
System.out.println("子类B的静态代码块");
}
public B() {
System.out.println("子类B的构造方法");
}
{
System.out.println("子类B的构造代码块");
}
}
public class JavaTest1 {
public static void main(String[] args) {
new B();
}
}
输出结果:
父类A的静态代码块0
staticStr = 1234
静态成员变量显示初始化
iniStaticStr
父类A的静态代码块
父类A的静态代码块1
子类B的静态代码块
父类A的构造代码块0
str = 123
非静态成员变量显示初始化
iniStr
父类A的构造代码块
父类A的构造代码块1
父类A的构造方法
静态成员变量 = iniStaticStr, 非静态成员变量 = iniStr
子类B的构造代码块
子类B的构造方法
具体问题描述:
1、代码块与成员变量的执行顺序是怎样的?如果代码块先于成员变量执行,那此时的成员变量并没用被声明,那为什么能对成员变量进行赋值?
2、假如是成员变量先于代码块执行,为什么代码块中使用System语句输出操作会提示非法向前引用?
3、成员变量的初始化过程是否是一下过程?
1)默认初始化
2)显示初始化(包括代码块中的显示初始化)
3)构造初始化