《JAVA编程思想》学习备忘(第155页:Initialization & Cleanup)-5

续《JAVA编程思想》学习备忘(第155页:Initialization & Cleanup)-4
Member initialization
如果一个类中的属性为原始数据类型,它将会确保有一个初始值。以下程序为一例证:
import static staticPrint.Print.print;
public class InitialValues{
    boolean t;
    char c;
    byte b;
    short s;
    int i;
    long l;
    float f;
    double d;
    InitialValues reference;
    void printInitialValues(){
        print("Data type    Initial value");
        print("boolean      " + t);
        print("char        [" + c + "]");
        print("byte         " + b);
        print("short        " + s);
        print("int          " + i);
        print("long         " + l);
        print("float        " + f);
        print("double       " + d);
        print("reference    " + reference);
    }
    public static void main(String[] args){
        InitialValues iv = new InitialValues();
        iv.printInitialValues();
       
    }
}
输出结果如下:
Data type        Initial value
boolean          false
char             [ ]
byte             0
short            0
int              0
long             0
float            0.0
double           0.0
reference        null
通过观察,可以清楚地看到“自动付值”的结果。char输出一空格,类的对象reference 则输出为 null 。
 
Specifying initialization
你怎样给一个变量一个初值?简单而直接的方法是在类中定义这个变量之处付值。(例子略)
你同样也可如上所述初始化非原始数据类型对象。(使用new实例化)。使用未实例化付初值的对象将引发异常。
你甚至可以调用一个方法来付初值:
public class MethodInit{
    int i = f();
    int f(){ return 11; }
}
以上这个方法当然可以有参,但那些参数不能为尚未初始化的类成员,可这样:
public class MethodInit2{
    int i = f();
    int j = g(i);
    int f(){ return 11; }
    int g(int n){ return n * 10; }
但你可以这样做:
public class MethodInit3{
    //! int j = g(i); // Illegal forward reference
    int i = f();
    int f(){ return 11; }
    int g(int n){ return n*10; }
}
 
Constructor initialization
构造方法初始化。
记住一点:你不能预先排除自动初始化,它发生在进入构造方法之前。
举例:
//:initialization/Counter.java
public class Counter{
    int i;
    Counter(){ i=7; }
    //...
}
这样i首先被初始化为0,然后才是7 。
 
Order of initialization
类中,初始化顺序决定于类中属性定义的顺序。属性的定义可能是分散的和在方法定义之间的,但在任何方法调用之前属性就被初始化了——即使是构造方法。
举例:
//:initialization/OrderOfInitializaion.java
// Demonstrates initialization order.
import static staticPrint.Print.print;
//When the constructor is called to create a
//Window object.you'll see a message:
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 constructor is done
    }
}
输出结果:
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()
 
static data initialization
不管建立了多少对象,仅有单一的存储域为静态空间。你不能给本地变量申请static关键字,它仅用于域属性,如果一个域属性为静态的原始数据类型并且未初始化,它会得到标准的初始化类值,如果它是一个对象的形参,默认初始化值为null 。
如果你要在定义之处初始化,它看起来与非静态是同样的。
举例:
//:initialization/StaticInitialization.java
//Specifying initial values in a class definition.
import static staticPrint.Print.print;
 
class Bowl{
    Bowl(int marker){
        print("Bowl("+marker+")");
    }
    void f1(in 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)
从输出结果可以看到,静态的初始化仅在它必要时发生。如果你不创建一个Table对象,你永不会选择Table.bowl1或者Table.bowl2,static Bowl1和static Bowl2将永不会被创建。它们仅当首个Table对象被创建时初始化(或者首次静态存取发生)。此后,静态对象不再被初始化。静态初始化顺序优先。
 
To summarize the process of creating an object,consider a class called Dog:
1.Even though it doesn't explicitly use the static keyword,the constructor is actually a static method.So the first time an object of type Dog is created,or the first time a static method or static field of class Dog is accessed,the Java interpreter must locate Dog.class,which it does by serching through the classpath.
2.As Dog.class is loaded(creating a Class object,which you'll learn about later),all of its static initializaters are run.Thus,static initialization takes place only once,as the Class object is loaded for the first time.
3.When you create a new Dog(),the construction process for a Dog object first allocates enough storage object on the heap.
4.This storage is wiped to zero,automatically setting all the primitives in the Dog object to their default values(zero for numbers and the equivalent for boolean and char)and the references to null.
5.Any initializations that occur at the point of field definition are executed.
6.Constructors are executed.As you shall see in the Reusing Classes chapter,this might actually involve a fair amount of activity,especially when inheritance is involved.
 
Explicit static initialization
Java allows you to group other static initializations inside a special"static clause"(sometimes called a static block)in a class.It looks like this:
//:initialization/Spoon.java
public class Spoon{
    static int i;
    static{
        i = 47;
    }
}
It appears to be a method,but it's just the static keyword followed by a block of code.This code,like other static initializations,is executed only once:the first time you make an object of that class or the first time you access a static member of that class(even if you never make an object of that class).For example:
//:initialization/ExplicitStatic.java
//Explicit static initilization with the "static" clause.
import static staticPrint.Print.print;
class Cup{
    Cup(int marker){
        print("Cup("+marker+")");
    }
    void f(int marker){
        print("f("+marker+")");
    }
}
class Cups{
    static Cup cup1;
    static Cup cup2;
    static{
        cup1 = new Cup(1);
        cup2 = new Cup(2);
    }
    Cups(){
        print("Cups()");
    }
}
public class ExplicitStatic{
    public static void main(String[] args){
        print("Inside main()");
        Cups.Cup1.f(99);//(1)
    }
    //static Cups cups1 = new Cups();//(2)
    //static Cups cups2 = new Cups();//(2)
}
输出结果:
Cup(1)
Cup(2)
f(99)
  (待续)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值