成员初始化

  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. Unbalanced calls to begin/end appearance transitions for **

    在自定义UITabBarController中点击视图跳转的时候,有可能就出现这个问题, 解决方法就是在自定义的UITabBarController中的视图显示消失通知方法中添加如下方法: - (vo ...

  2. c语言实现牛顿迭代法

    #include<stdio.h> #include<stdlib.h> #include<math.h> #include<float.h> #inc ...

  3. java中的foreach循环

    foreach语句是java5的新特征之一,在遍历数组.集合方面,foreach为开发人员提供了极大的方便. foreach语句是for语句的特殊简化版本,但是foreach语句并不能完全取代for语 ...

  4. Ubuntu下iperf的安装

    (1)下载 链接:http://sourceforge.net/projects/iperf/files/?source=navbar   资源:iperf-2.0.5.tar.gz (2)解压 #t ...

  5. HTMlhleper

    @{ ViewBag.Title = "Index";} <h2>Index</h2> <div> @{ int id=12121; var I ...

  6. .NET笔试题集(二)

    1.using关键字有什么用?什么是IDisposable? using可以声明namespace的引入,还可以实现非托管资源的释放,实现了IDisposiable的类在using中创建,using结 ...

  7. iOS 自动化打包

    理想的情况:不打开工程的情况下,直接双击就能打包出一个IPA文件,这样就可以让测试直接使用 itools 进行安装. 分如下两种情况: 1)不依赖cocoapod  管理项目的自动化. 如果没有一个简 ...

  8. Jenkins_Maven_Git 持续集成及自动化部署 GentOS版

    1.安装JDK JDK下载: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 新 ...

  9. Javascript轮播 支持平滑和渐隐两种效果(可以只有两张图)

    先上两种轮播效果:渐隐和移动   效果一:渐隐 1 2 3 4 效果二:移动 1 2 3 4 接下来,我们来大致说下整个轮播的思路: 一.先来看简单的,移动的,先上来一个图----移动效果图: 说明: ...

  10. [解决方案] pythonchallenge level 6

    查看页面代码,知道找zip www.pythonchallenge.com/pc/def/channel.zip,查看zip下的readme.txt知道从90052,跑一遍知道要收集zip的comme ...