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