码迷,mamicode.com
首页 > 其他好文 > 详细

成员初始化

时间:2015-12-24 16:41:39      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:成员初始化

1. 变量初始化

在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,

那些变量仍会在调用任何方法之前得到初始化——甚至在构建器调用之前。

例子:

class Tag 
{
  Tag(int marker) {
  System.out.println("Tag(" + marker + ")");
  }
}
class Card
 {
  Tag t1 = new Tag(1); // Before constructor
  Card() {
    // Indicate we‘re in the constructor:
    System.out.println("Card()");
    t3 = new Tag(33); // Re-initialize t3
  }
  Tag t2 = new Tag(2); // After constructor
  void f() {
    System.out.println("f()");
  }
  Tag t3 = new Tag(3); // At end
}
public class OrderOfInitialization
 {
  public static void main(String[] args) {
    Card t = new Card();
    t.f(); // Shows that construction is done
  }
}

结果:

Tag(1)

Tag(2)

Tag(3)

Card()

Tag(33)

f()

2.静态数据的初始化

若数据是静态的(static),那么同样的事情就会发生;如果它属于一个基本类型(主类型),而且未对其初始化,就会自动获得自己的标准基本类型初始值;如果它是指向一个对象的句柄,那么除非新建一个对象,并将句柄同它连接起来,否则就会得到一个空值(NULL)。

例子:

class Bowl 
{
  Bowl(int marker) {
    System.out.println("Bowl(" + marker + ")");
  }
  void f(int marker) {
    System.out.println("f(" + marker + ")");
  }
}
class Table
 {
  static Bowl b1 = new Bowl(1);
  Table() {
    System.out.println("Table()");
    b2.f(1);
  }
  void f2(int marker) {
    System.out.println("f2(" + marker + ")");
  }
  static Bowl b2 = new Bowl(2);
}
class Cupboard 
{
  Bowl b3 = new Bowl(3);
  static Bowl b4 = new Bowl(4);
  Cupboard() {
    System.out.println("Cupboard()");
    b4.f(2);
  }
  void f3(int marker) {
    System.out.println("f3(" + marker + ")");
  }
  static Bowl b5 = new Bowl(5);
}
public class StaticInitialization
{
  public static void main(String[] args) {
    System.out.println( "Creating new Cupboard() in main");
    new Cupboard();
    System.out.println("Creating new Cupboard() in main");
    new Cupboard();
    t2.f2(1);
    t3.f3(1);
  }
  static Table t2 = new Table();
  static Cupboard t3 = new Cupboard();
}

结果:

Bowl(1)

Bowl(2)

Table()

f(1)

Bowl(4)

Bowl(5)

Bowl(3)

Cupboard()

f(2)

Creating new Cupboard() in main

Bowl(3)

Cupboard()

f(2)

Creating new Cupboard() in main

Bowl(3)

Cupboard()

f(2)

f2(1)

f3(1)

static初始化只有在必要的时候才会进行。如果不创建一个 Table 对象,而且永远都不引用Table.b1 Table.b2,那么 static Bowl b1 b2 永远都不会创建。然而,只有在创建了第一个Table 对象之后(或者发生了第一次static 访问),它们才会创建。在那以后,static 对象不会重新初始化。Static仅执行一次——首次生成那个类的一个对象时,或者首次访问属于那个类的一个 static 成员时。(即便从未生成过那个类的对象)。

初始化的顺序是首先static(如果它们尚未由前一次对象创建过程初始化),接着是非static 对象。

在这里有必要总结一下对象的创建过程。请考虑一个名为 Dog的类:

(1) 类型为 Dog的一个对象首次创建时,或者Dog 类的static方法/static 字段首次访问时,

   Java 解释器必须找到Dog.class(在事先设好的类路径里搜索)。

(2) 找到Dog.class 后(它会创建一个 Class对象,这将在后面学到),它的所有 static初始

   化模块都会运行。因此,static初始化仅发生一次——在 Class 对象首次载入的时候。

(3) 创建一个new Dog()时,Dog 对象的构建进程首先会在内存堆(Heap)里为一个 Dog对 

   象分配足够多的存储空间。

(4) 这种存储空间会清为零,将Dog中的所有基本类型设为它们的默认值(零用于数字,以 

   及 booleanchar 的等价设定)。

(5) 进行字段定义时发生的所有初始化都会执行。

(6) 执行构建器。正如第章将要讲到的那样,这实际可能要求进行相当多的操作,特别是

   在涉及继承的时候。

3. 明确进行的静态初始化(静态块)

Java 允许我们将其他static初始化工作划分到类内一个特殊的“static 构建从句”(有时也叫作“静态块”)里。

尽管看起来象个方法,但它实际只是一个static 关键字,后面跟随一个方法主体。与其他 static初始化一样,这段代码仅执行一次——首次生成那个类的一个对象时,或者首次访问属于那个类的一个 static 成员时(即便从未生成过那个类的对象)。

例子:

class Cup
 {
  Cup(int marker) {
    System.out.println("Cup(" + marker + ")");
  }
  void f(int marker) {
    System.out.println("f(" + marker + ")");
  }
}
class Cups
 {
  static Cup c1;
  static Cup c2;
  static {
    c1 = new Cup(1);
    c2 = new Cup(2);
  }
  Cups() {
    System.out.println("Cups()");
  }
}
public class ExplicitStatic 
{
  public static void main(String[] args) {
    System.out.println("Inside main()");
    Cups.c1.f(99); // (1)
  }
  static Cups x = new Cups(); // (2)
  static Cups y = new Cups(); // (2)
}

在标记为(1)的行内访问 static 对象c1 的时候,或在行(1)标记为注释,同时(2)行不标记成注释的时候,用于Cups 的 static初始化模块就会运行。若(1)(2)都被标记成注释,则用于 Cups static 初始化进程永远不会发生。

4. 非静态实例的初始化(非静态块)

针对每个对象的非静态变量的初始化,Java 1.1 提供了一种类似的语法格式。

例子:

class Mug
{
  Mug(int marker) {
    System.out.println("Mug(" + marker + ")");
  }
  void f(int marker) {
    System.out.println("f(" + marker + ")");
  }
}
public class Mugs 
{
  Mug c1;
  Mug c2;
  {
    c1 = new Mug(1);
    c2 = new Mug(2);
    System.out.println("c1 & c2 initialized");
  }
  Mugs() {
    System.out.println("Mugs()");
  }
  public static void main(String[] args) {
    System.out.println("Inside main()");
    Mugs x = new Mugs();
  }
}

它看起来与静态初始化从句极其相似,只是static 关键字从里面消失了。为支持对“匿名内部类”的初始化,必须采用这一语法格式。



成员初始化

标签:成员初始化

原文地址:http://zhenzhuangde.blog.51cto.com/10697385/1727847

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!