發新話題

Java 教程《語法說明》定義欄位(變數)

Java 教程《語法說明》定義欄位(變數)

■ 定義欄位(變數)
[field-modifiers]  dataType  variableName;
  或
[field-modifiers]  dataType  variableName =  expression;

[說明]
1. 存取類別變數需使用 . 運算元
 類別名稱.變數名稱;     // 呼叫static變數
 或  物件名稱.變數名稱;  // 這是物件變數
2. instance variable 描述此 instance 的狀態(state), 其宣告在類別範圍(scope)內。
 區域變數(local variable)為一種暫存資訊(temporary storage place of information),宣告在method 內。
 兩者(instant variable 和 local variable)中只有 instance variable 可使用修飾子(modifier)加以宣告;local variable 可使用 final 修飾。
 如果 instance variable 有指定初值,則在建立某物件執行呼叫建構子前,該值即已存在此 variable 內。
3. 變數可選擇性的提供初始值。

[範例]
public class A {
  ‥‥
  private int money;
}

[註]
● 除利用 constructor 指定 variables 初值外,Java 提供另一種方法指定 variables 的初值:initializers。
 Java 有 2 種 initializers:
   ‧instance variable initializers 以及 class variable initializers
   ‧instance initializers 以及 static initializers

1> Instance variable initializers
所謂的 instance variable initializer,即是利用等號(=)和 expression 設定初值。等號左邊為 instance variable,等號右邊
為 expression。

[範例1]
class NewMachine {
  private String status;
  public NewMachine( ) {
    status = "Good";  // 在建構子內設定 instance variable 的初值
  }
  ......
}

[範例2]
class NewMachine {
  private int status = 355;  // "= 355" is an initializer
  // no constructor here
  ......
}

2> instance initializers
Java 1.1 後新增利用 instance initializers 方式設定 instance variable 的初值。
Instance initializers,也可稱為 instance initialization blocks,即將初值設定寫在區塊(block)內(以 { } 括起來的區塊),該區塊位於 class 的
主體(body)內,但位於該 class內所宣告的任何 method  體外,但可以寫在建構子內(建構子並不是 method)。
instance variable initializers 適用下列情況:
  (a) initializer code 必須捕捉例外;或
  (b) 執行複雜的運算。
  (c) 使用在 anonymous inner class內,因其 class 內無法宣告任何的 constructors。
在 instance initializer 內的程式碼在物件被建立時(使用 new 指令)執行,並且不被傳回(return)。而且 instance initializers 對例外有其特殊規則。

[範例] 利用 instance initializers 設定 instance variable 的初值
class NewMachine {
  private boolean status ;
  // 以下的 { } 區塊即所謂的 instance initializer
  {
   status = "good";          // 使用 new NewMachine( ) 產生一個新物件時,便設定status的初值。
  }
  ......
}


3> Class Variable Initializers
class Variable Initializers 利用等號和表示式(expression)指定初值。
class A {
  private int x;
  private static int y = 10;
}


4> Static Initialization Blocks (或稱為 Static Initializer)
a.  如果一個 class variable 初始化的過程太過複雜,可以使用 static initialization block 完成該工作。
b.  所謂的 static initialization block 是在 static 後加上 { } 區塊,並將 class variable 的初值化工作寫在區塊內。
c.  在程式碼中 class variable block 可以多次出現,並沒有限制。
d.  static initialization blocks 可存取同一個 class 內的 static methods

class ClassName {
  ...
  static {  // static initialization blocks
    // code for the static initialization goes here
  }
  ...
}


● Initializers 無法前置參考(Forward References)。
1. 所謂的 forward reference 意指參考到在後面宣告的變數。
2. 當物件被建立時,根據程式碼內容的先後出現順序執行 initializers。而 forward-referencing 規則避免 initializers 使用
 到未初始化的 variables。
3. 但在 left hand side 的 assignment 不受 Forward References 限制。

[範例]
class A {
  private int x = 20;
  private int y = x * 5;  // OK
  ...
}

[範例]
class A {
  private int y = x * 5;  // error
  private int y = x ;  // error
  private int y = x = 5;  // OK
  private int x = 20;
  ...
}

[範例] 使用 method 可避開 forward reference 規則的限制:
class A {
  private int y = initY( );  // 可通過編譯,y 值為0
  private int x = 20;
  private int initY( ) {
    return x * 4;
  }
  ...
}

[範例]
static {
     x = 0;
}
static int x;
static int z = x + 1;

但是  
static {
     x = 0;
     z = x + 1;     // error, illegal forward reference
}
static int x;
static int z;

[範例]
class {
      static { myStaticVariable = 10; }     // OK
      {  myInstanceVariable = 5;  }     // OK
      static int myStaticVariable;
      int myInstanceVariable;
}

[範例]
class UseBeforeDeclaration {   // JLS -8.3.2.3
    static {
        x =100;      // OK
        int y = x + 1;       //error --read before declaration; illegal forward reference
        int v = x= 3;      // ok
        int z = UseBeforeDeclaration.x * 2;       // ok
        Object o = new Object( ) {
             void foo( ) { x++; }      // ok
             { x++; }   // ok
        };
    } // static initializer

    {
       j = 20;       //ok
       j = j + 1;       //error. illegal forward reference
       int k = j = j+1;        //??. illegal forward reference
       int n = j = 300;      //ok
       int h = j++;        //error. illegal forward reference
       int l = this.j * 3;       // ok - not accessed via simple name
       Object o = new Object( ){
             void foo( ){ j++; }       // ok - occurs in a different class
             { j = j + 1; }       // ok - occurs in a different class
       };
    }
   
    int w = x= 3;      // ok - x at left hand side of assignment
    int p = x;       // ok - instance initializers may access static fields
    static int u =(new Object( ) { int bar( ){ return x; } }).bar( );    // ok - occurs in a different class
    static int  x;
    int m = j = 4;        // ok - j at left hand side of assignment
    int o = (new Object( ) { int bar( ) { return j; } }).bar( );        // ok - occurs in a different class
    int j;
} // class

[範例]
class Test {
    Test( ) { k = 2; }    // ok, method 沒有 forward reference 的問題
    int i = 5;  
    int j = i;
    int k;
}

[範例] 下面範例中的 class 雖然沒有包含 class variables,但仍可使用static Initialization Blocks。
    程式中的Hello World! 比 main( ) 更早執行。
class StaticinItialization {
  public static void main(String args[ ]) {
    System.out.println("Run After hello world..");
  }
  static {
    System.out.println("Hello world!");
  }
}

包含在 static initialization block 內的程式碼不僅可以設定 class variables 的初值,也可以包括一般 static method 所能執
行的程式碼在內,但不能向前參照 class variable。

[範例]
class StaticGreeting2 {
  public static void main(String args[ ]) {  // 注意此處 main( ) 未執行任何程式碼
  }
  static {
    printGreeting( );
  }
  String s = "Hello !";
  static void printGreeting( ) {
    System.out.println(s);
  }
}

執行結果>>
null

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。