疯狂java讲义第六章 6.4节FinalErrorTest疑问

书中讲:java不会对final修饰的成员变量隐式初始化,要求作者显示初始化。但
是在后面的例子中,变量age还未初始化之前直接用输出语句输出age编译报错,
而用类中定义的函数printAge()就不报错。实质还是同一个操作,这作何解释?
代码如下,求各路大神解答,感激不尽。


public class FinalError
{
    // 定义一个final修饰的实例变量
    // 系统不会对final成员变量进行默认初始化
    final int age;
    {
        //这里对未赋值的age直接输出报错
        //System.out.println(age);
        //这里用函数去调用输出就不报错
        printAge();
        age = 6;
        System.out.println(age);
    }
    public void printAge(){
        System.out.println(age);
    }
    public static void main(String[] args)
    {
        new FinalError();
    }
}

直接在类中定义且没有加static关键字的代码块称为{}构造代码块。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数。这个直接一对大括号中间的代码称为构造代码块。其中的代码是优先于构造函数的,所以那时还没有对属性初始化值。int的初始化值是0