A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 朴日男 中级黑马   /  2014-9-29 19:38  /  1688 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 朴日男 于 2014-9-29 19:44 编辑

class StaticCode
{
    int num = 9; /* 这变量什么时候加载???也是跟着类加载吗??? */
    StaticCode()
    {
        System.out.println("b");
    }
    static
    {
        System.out.println("a"); /*静态代码块*/
    }
    {
        System.out.println("c" + this.num); /*构造代码块*/
    }
    StaticCode(int x)
    {
        System.out.println("d");
    }
    public static void show()
    {
        System.out.println("show run");
    }
}
public class StaticCodeDemo
{
    public static void main(String[] args)
    {
        new StaticCode(4);/* 加载类--> a c9 -->调用构造函数 d */
        /* 老师说的是 a c d 没有9,int num = 9 什么时候加载??? */
    }
}

/*
老师说的结果:    a c d
Eclipse控制台输出结果:    a c9 d
debug:    a c9 d
凌乱了...int num = 9 到底加载与否??? 构造代码块和静态代码块 哪个优先执行呢>? 是按顺序吗?

*/

评分

参与人数 1技术分 +1 收起 理由
敏敏好学 + 1

查看全部评分

7 个回复

倒序浏览
int num是成员变量,你New了对象自然就加载了。首先是静态代码块执行,用来初始化类,所以a。然后构造代码块是给所有对象初始化,所以c9。最后是构造函数给特定函数初始化,因为你的构造函数传入了一个参数,所以是d

评分

参与人数 1技术分 +1 收起 理由
敏敏好学 + 1

查看全部评分

回复 使用道具 举报 1 0
LFW 发表于 2014-9-29 20:26
int num是成员变量,你New了对象自然就加载了。首先是静态代码块执行,用来初始化类,所以a。然后构造代码 ...

感谢...:)
回复 使用道具 举报
静态代码块比构造代码块先执行。只要类一进行加载,静态代码块就对类进行初始化,接着就是new 在堆内存中开辟内存空间,然后特有属性开始初始化赋值,就是你这里的num了。这一步完了,就到了执行构造代码块了,它是对对象进行初始化的(所以它晚于静态代码块),接着执行相应的构造函数。
回复 使用道具 举报
你那是显示初始化,在静态代码块后执行!!!
回复 使用道具 举报
静态代码块无条件先执行!
回复 使用道具 举报
简单的代码块运行顺序: 静态代码块-----(成员)构造代码块-------局部代码块-------------构造函数方法体。其实构造函数是最先走的 但是没走方法体,最后才走的构造函数的方法体
回复 使用道具 举报
本帖最后由 waylent 于 2014-9-30 00:15 编辑

初始化字段
正如你之前遇到的,你经常会在变量声明的时候初始化它的值:
  1. public class BedAndBreakfast {

  2.     // 初始化成10
  3.     public static int capacity = 10;

  4.     // 初始化成false
  5.     private boolean full = false;
  6. }
复制代码
当初始化值可以轻易获取或者初始化代码可以用一行完成时,这么做是行的通的。但是,这种形式的初始化因为它的简洁性而有局限性。如果初始化需要一些逻辑(例如,错误处理或者用for循环填充一个复杂的数组),简单的分配初始值是不够的。实例变量可以在构造函数中初始化,这样在构造函数中就可以写错误处理或者其他逻辑。为了使类变量(静态变量)也具有相同的能力,Java编程语言提供了静态代码块(static initialization blocks).

静态代码块
一个静态代码块通常如下:
  1. static {
  2.     // 初始化代码写这里
  3. }
复制代码
一个类可以有许多静态代码块,它们可以出现在类结构体(class body)中的任何地方.这些静态代码块按在源代码中的出现顺序被调用。

有一种方法可以替代静态代码块,你可以写一个私有静态方法:
  1. class Whatever {
  2.     public static varType myVar = initializeClassVariable();
  3.         
  4.     private static varType initializeClassVariable() {
  5.         // 初始化代码写这里
  6.     }
  7. }
复制代码
私有静态方法初始化静态字段的优势是,你可以不实例化类就重新初始化这个静态字段。

初始化实例成员
一般情况下,你会将初始化实例变量的代码放到构造函数中。有两种方法可以替代构造函数初始化实例变量:构造代码块(initializer blocks)final方法


构造代码块看起来很像静态代码块,只不过没有static关键字:
  1. {
  2.     // 初始化代码写这里
  3. }
复制代码
Java编译器会拷贝构造代码块到每一个构造函数。因此这个方法被用于在多个构造函数间共享一段代码。



final方法不能被子类覆写(override)。下面是一个用final方法初始化实例变量的一个例子:
  1. class Whatever {
  2.     private varType myVar = initializeInstanceVariable();
  3.         
  4.     protected final varType initializeInstanceVariable() {
  5.         // 初始化代码写这里
  6.     }
复制代码
这种方法在子类想重用初始化方法时特别有效。这个方法之所以要加final关键字,是因为在实例初始化期间调用没有final关键字修饰的方法会引起问题。

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马