成员初始化

  Java尽力保证:所有变量在使用前都能得到恰当的初始化。

  对于方法的局部变量,Java会以编译时报错的形式贯彻这种保证,比如:

 void f()
 {
       int i;  //这里编译时就会报错,未初始化
 }

  但是如果是类的数据成员,情况会有所不同。类的每个基本类型数据成员会保证一个默认初始值,通常为0,布尔型就是false,引用类型会为null。

  指定初始化

    (1 直接在类里定义时写变量等于多少(这样在C++中是不允许的)如, 

public class initialV
{
    int a=1;
    char c = 'c';
    //...等等
}

构造器初始化

  可以用构造器进行初始化。但应注意:无法阻止自动初始化的进行,它将在构造器之前发生。

public class Counter
{
    int i;
    Counter()
    {
         i=7;
    }
}    

这里,i首先会被置0,然后变成7.对于所以基本类型和对象引用,包括在定义时已经指定初值的变量。这种情况都是成立的。

初始化顺序

  在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。如下例子

class Window {
  Window(int marker) { print("Window(" + marker + ")"); }
}

class House {
  Window w1 = new Window(1); // Before constructor
  House() {
    // Show that we're in the constructor:
    print("House()");
    w3 = new Window(33); // Reinitialize w3
  }
  Window w2 = new Window(2); // After constructor
  void f() { print("f()"); }
  Window w3 = new Window(3); // At end
}

public class OrderOfInitialization {
  public static void main(String[] args) {
    House h = new House();
    h.f(); // Shows that construction is done
  }
} /* 输出:
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()
*///:~

静态数据的初始化

   类的静态成员 属于 类 而不是类 的实例。所以 ,无论你创建多少个对象,静态成员指占用一份存储区域。static关键字不能应用于局部变量,因此只能作用于域。初始化方式和非静态一样。

   给看一个挺长的例子,看不懂直接调后面的解析。

import static net.mindview.util.Print.*;

class Bowl {
  Bowl(int marker) {
    print("Bowl(" + marker + ")");
  }
  void f1(int marker) {
    print("f1(" + marker + ")");
  }
}

class Table {
  static Bowl bowl1 = new Bowl(1);
  Table() {
    print("Table()");
    bowl2.f1(1);
  }
  void f2(int marker) {
    print("f2(" + marker + ")");
  }
  static Bowl bowl2 = new Bowl(2);
}

class Cupboard {
  Bowl bowl3 = new Bowl(3);
  static Bowl bowl4 = new Bowl(4);
  Cupboard() {
    print("Cupboard()");
    bowl4.f1(2);
  }
  void f3(int marker) {
    print("f3(" + marker + ")");
  }
  static Bowl bowl5 = new Bowl(5);
}

public class StaticInitialization {
  public static void main(String[] args) {
    print("Creating new Cupboard() in main");
    new Cupboard();
    print("Creating new Cupboard() in main");
    new Cupboard();
    table.f2(1);
    cupboard.f3(1);
  }
  static Table table = new Table();
  static Cupboard cupboard = new Cupboard();
} /* 输出:
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)
*///:~

  解析下这个Demo:要执行main()(静态方法) ,必须加载StaticInitialization 类,然后其静态域table和cupboard被初始化,这将导致他们对应的类页被加载,并且由于他们也都包含静态的Bowl对象,因此Bow随后也被加载了。(恍然大悟)

  理论得出:静态初始化只有在必要时刻才会进行。如果不创建Table对象,也不引用Table.b1或Table.b2,name静态的Bowl b1和b2永远都不会被创建。只有在第一个Table对象被创建(或其第一次被访问了静态数据)的时候,它们才会被初始化。此后,静态对象不会再次被初始化

显式的静态初始化

  Java允许将多个静态初始化动作组织成一个特殊的“静态字句”(也称 “静态块”),如下。

public class Spoon {
  static int i;
  static {
    i = 47;
  }
} ///:~

  尽管上面的代码看起来像个方法,但它实际只是一段跟在static关键字后面的代码。与其他静态初始化动作一样,这段代码只执行一次:同样的时间,当第一次生成这个类的一个对象时,或者首次访问属于那个类的静态数据成员时(即便从未生成过那个类)。

非静态实例初始化

  用来初始化每一个对象的非静态变量。如下

class Mug {
  Mug(int marker) {
    print("Mug(" + marker + ")");
  }
  void f(int marker) {
    print("f(" + marker + ")");
  }
}

public class Mugs {
  Mug mug1;
  Mug mug2;
  {
    mug1 = new Mug(1);
    mug2 = new Mug(2);
    print("mug1 & mug2 initialized");
  }
  Mugs() {
    print("Mugs()");
  }
  Mugs(int i) {
    print("Mugs(int)");
  }
  public static void main(String[] args) {
    print("Inside main()");
    new Mugs();
    print("new Mugs() completed");
    new Mugs(1);
    print("new Mugs(1) completed");
  }
} /* 输出:
Inside main()
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs()
new Mugs() completed
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs(int)
new Mugs(1) completed
*///:~

这是无论调用了哪个显式构造器,某些操作都会发生。从输出中 可以看到实例化字句 是在构造器之前执行的。

《java编程思想》读书笔记(二)第五章(2)的更多相关文章

  1. 《Java编程思想》笔记 第十五章 泛型

    1 泛型 “泛型”意思就是适用于许多类型. 使用泛型的目的之一: 指定容器持有什么类型,让编译器确保正确性,而不是在运行期发现错误. 这个容器可以看成是有其他类型对象作为成员的类,而不单单只是JDK中 ...

  2. Java编程思想读书笔记_第7章

    final关键字类似const: import java.util.*; public class FinalData { static Random rand = new Random(47); f ...

  3. Java编程思想读书笔记_第6章

    如何创建一个包: 比如创建一个包名为com.huawei 则在一个目录下如(d:\java)创建目录com/huawei 然后在huawei目录下创建一个文件Assist.java package c ...

  4. Java编程思想读书笔记_第三章

    本章提到的关于==的部分,一个完整的实验如下: class Test { public static void main(String[] args) { Integer i = new Intege ...

  5. Java编程思想读书笔记_第8章

    覆盖私有方法 class Father { private void f() { System.out.println("Father::f()"); } public stati ...

  6. Java编程思想读书笔记_第6章(访问权限)

    四种访问权限: public private 包访问权限 protected 如果没有明确指定package,则属于默认包 package access.dessert; public class C ...

  7. JAVA编程思想读书笔记(五)--多线程

    接上篇JAVA编程思想读书笔记(四)--对象的克隆 No1: daemon Thread(守护线程) 参考http://blog.csdn.net/pony_maggie/article/detail ...

  8. JAVA编程思想读书笔记(二)--容器

    接上篇JAVA编程思想读书笔记(一) 第八章.对象的容纳 No1: java提供了四种类型的集合类:Vector(矢量).BitSet(位集).Stack(堆栈).Hashtable(散列表) No2 ...

  9. JAVA编程思想读书笔记(三)--RTTI

    接上篇JAVA编程思想读书笔记(二) 第十一章 运行期类型判定 No1: 对于作为程序一部分的每个类,它们都有一个Class对象.换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说, ...

  10. JAVA编程思想读书笔记(四)--对象的克隆

    接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObje ...

随机推荐

  1. linux下查看tomcat和jdk版本号

    linux下查看tomcat和jdk版本号的命令: 这个需要进入到bin目录下面 ,执行"./version.sh"命令 [root@hncsweb bin]# ./version ...

  2. 例子:Execution Model Sample - 应用状态保存

    WP中,当你的应用被切换到后台 后,就进入了休眠状态,然后当一个应用从墓碑恢复时,如何恢复相应的状态,该例子就演示了如何保存和恢复UI以及APP相关状态. 这里有一篇很好的文章,请参见: http:/ ...

  3. Python开发入门与实战20-微信开发配置

    随着移动互联网时代的来临,微信已经成为移动互联网移动端的主要入口,现在很多的大型企业都有自己的微信服务号,如:银行业有自己的微银行,基金公司的公众服务号.通过微信入口可以方便快速的实现企业提供的服务. ...

  4. string和char*的相互转换

    原文地址: 点击打开链接

  5. entity framework 新手入门篇(2)-entity framework基本的增删改查

    经过前两节的简单描述,终于可以进入entity framework的使用部分了.本节将对entity framework原生的增删改查进行讲解. 承接上面的部分,我们有一个叫做House的数据库,其中 ...

  6. CSS实现三角形

    突然想起搞一把三角形. 简单来说: 建一个div  宽度.高度设为0 添加两个样式: border 和 border-color 如果需要一个三角形把其他边框都设为透明 transparent < ...

  7. iOS AVCaptureSession 小视频开发总结,支持设备旋转

    iOS开发中当我们想要自定义相机拍照或摄像界面时,UIImagePickerController无法满足我们的需求,这时候我们可以使用AVFoundation.framework这个framework ...

  8. 设置vim默认参数 例如设置默认背景颜色

    因个人喜好问题,本人使用vim的时候喜欢将背景颜色设为dark. 但是每次打开一个vim的时候都要重新设置一次,感觉非常麻烦. 总要输入[Esc] :set bg=dark很不方便 粗暴的办法是直接进 ...

  9. linux驱动之LCD

    LCD程序步骤:1. 分配一个fb_info 2. 设置 3. 硬件相关的操作4. 注册 register_framebuffer 5.入口函数 6.出口函数 #include <linux/s ...

  10. Android SDK ADT下载地址

    http://dl.google.com/android/android-sdk_rXX-windows.zip http://dl.google.com/android/ADT-X.X.X.zip ...