實踐2:對不變的data和object reference使用final
實踐3:缺省情況下所有non-static函數(shù)都可被重寫
實踐4:在array和Vectors之間慎重選擇
實踐5:多態(tài)(polymorphism)優(yōu)于instanceof
實踐6:必要時才使用instanceof
實踐7:一旦不需要object reference,就將它設為null
實踐1:參數(shù)以by value方式而非by reference方式傳遞
class PassByValue {
public static void modifyPoint(Point pt, int j) {
pt.setLocation(5, 5); // 1
j = 15;
System.out.println("During modifyPoint " + "pt = " + pt + " and j = " + j);
}
public static void main(String args[]) {
Point p = new Point(0, 0); // 2
int i = 10;
System.out.println("Before modifyPoint " + "p = " + p + " and i = " + i);
modifyPoint(p, i); // 3
System.out.println("After modifyPoint " + "p = " + p + " and i = " + i);
}
}
程序輸出如下:
During modifyPoint pt = java.awt.Point[x=5,y=5] and j = 15
After modifyPoint p = java.awt.Point[x=5,y=5] and i = 10
這顯示modifyPoint()改變了//2 所建立的Point對象,卻沒有改變int i。在main()之中,i被賦值10.由于參數(shù)通過by value方式傳遞,所以modifyPoint()收到i的一個副本,然后它將這個副本改為15并返回。main()內(nèi)的原值i并沒有受到影響。
對比之下,事實上modifyPoint() 是在與“Point 對象的 reference 的復件”打交道,而不是與“Point對象的復件”打交道。當p從main()被傳入modifyPoint()時,傳遞的是p(也就是一個reference)的復件。所以modifyPoint()是在與同一個對象打交道,只不過通過別名pt罷了。在進入modifyPoint()之后和執(zhí)行 //1 之前,這個對象看起來是這樣:

所以//1 執(zhí)行以后,這個Point對象已經(jīng)改變?yōu)?5,5)。
實踐2:對不變的data和object reference使用final
Java 關鍵字 final 用來表示常量數(shù)據(jù)。例如:
static final int someInt = 10;
//

}
這段代碼聲明了一個 static 類變量,命名為 someInt,并設其初值為10。
任何試圖修改 someInt 的代碼都將無法通過編譯。例如:

someInt = 9; // Error
//

關鍵字 final 可防止 classes 內(nèi)的 instance 數(shù)據(jù)遭到無意間的修改。如果我們想要一個常量對象,又該如何呢?例如:
private double rad;
public Circle(double r) {
rad = r;
}
public void setRadius(double r) {
rad = r;
}
public double radius() {
return rad;
}
}
public class FinalTest {
private static final Circle wheel = new Circle(5.0);
public static void main(String args[]) {
System.out.println("Radius of wheel is " + wheel.radius());
wheel.setRadius(7.4);
System.out.println("Radius of wheel is now " + wheel.radius());
}
}
這段代碼的輸出是:
Radius of wheel is now 7.4
在上述第一個示例中,我們企圖改變final 數(shù)據(jù)值時,編譯器會偵測出錯誤。
在第二個示例中,雖然代碼改變了 instance變量wheel的值,編譯器還是讓它通過了。我們已經(jīng)明確聲明wheel為final,它怎么還能被改變呢?
不,我們確實沒有改變 wheel 的值,我們改變的是wheel 所指對象的值。wheel 并無變化,仍然指向(代表)同一個對象。變量wheel是一個 object reference,它指向?qū)ο笏诘膆eap位置。有鑒如此,下面的代碼會怎樣?
private static final Circle wheel = new Circle(5.0);
public static void main(String args[]) {
System.out.println("Radius of wheel is " + wheel.radius());
wheel = new Circle(7.4); // 1
System.out.println("Radius of wheel is now " + wheel.radius());
}
}
編譯代碼,// 1 處出錯。由于我們企圖改變 final 型變量 wheel 的值,所以這個示例將產(chǎn)生編譯錯誤。換言之,代碼企圖令wheel指向其他對象。變量wheel是final,因此也是不可變的。它必須永遠指向同一個對象。然而wheel所指向的對象并不受關鍵字final的影響,因此是可變的。
關鍵字 final 只能防止變量值的改變。如果被聲明為 final 的變量是個 object reference,那么該reference不能被改變,必須永遠指向同一個對象,但被指的那個對象可以隨意改變內(nèi)部的屬性值。
實踐3:缺省情況下所有non-static函數(shù)都可以被覆蓋重寫
關鍵字final 在Java中有多重用途,即可被用于instance變量、static變量,也可用于classes或methods,用于類,表示該類不能有子類;用于方法,表示該方法不允許被子類覆蓋。實踐4:在array和vectors之間慎重選擇
array和Vector的比較
|
支持基本類型 |
支持對象 |
自動改變大小 |
速度快 |
array |
Yes |
Yes |
No |
Yes |
Vector |
No(1.5以上支持) |
Yes |
Yes |
No |
實踐5:多態(tài)(polymorphism)優(yōu)于instanceof
代碼1:instanceof方式
public int salary();
}
class Manager implements Employee {
private static final int mgrSal = 40000;
public int salary() {
return mgrSal;
}
}
class Programmer implements Employee {
private static final int prgSal = 50000;
private static final int prgBonus = 10000;
public int salary() {
return prgSal;
}
public int bonus() {
return prgBonus;
}
}
class Payroll {
public int calcPayroll(Employee emp) {
int money = emp.salary();
if (emp instanceof Programmer)
money += ((Programmer) emp).bonus(); // Calculate the bonus
return money;
}
public static void main(String args[]) {
Payroll pr = new Payroll();
Programmer prg = new Programmer();
Manager mgr = new Manager();
System.out.println("Payroll for Programmer is " + pr.calcPayroll(prg));
System.out.println("payroll for Manager is " + pr.calcPayroll(mgr));
}
}
代碼2:多態(tài)方式
public int salary();
public int bonus();
}
class Manager implements Employee {
private static final int mgrSal = 40000;
private static final int mgrBonus = 0;
public int salary() {
return mgrSal;
}
public int bonus() {
return mgrBonus;
}
}
class Programmer implements Employee {
private static final int prgSal = 50000;
private static final int prgBonus = 10000;
public int salary() {
return prgSal;
}
public int bonus() {
return prgBonus;
}
}
class Payroll {
public int calcPayroll(Employee emp) {
// Calculate the bonus. No instanceof check needed.
return emp.salary() + emp.bonus();
}
public static void main(String args[]) {
Payroll pr = new Payroll();
Programmer prg = new Programmer();
Manager mgr = new Manager();
System.out.println("Payroll for Programmer is " + pr.calcPayroll(prg));
System.out.println("Payroll for Manager is " + pr.calcPayroll(mgr));
}
}
實踐6:必要時才使用instanceof
class Shape {
}
class Circle extends Shape {
public double radius() {
return 5.7;
}
//

}
class Triangle extends Shape {
public boolean isRightTriangle() {
// Code to determine if triangle is right
return true;
}
//

}
class StoreShapes {
public static void main(String args[]) {
Vector shapeVector = new Vector(10);
shapeVector.add(new Triangle());
shapeVector.add(new Triangle());
shapeVector.add(new Circle());
//

// Assume many Triangles and Circles are added and removed
//

int size = shapeVector.size();
for (int i = 0; i < size; i++) {
Object o = shapeVector.get(i);
if (o instanceof Triangle) {
if (((Triangle) o).isRightTriangle()) {
//

}
} else if (o instanceof Circle) {
double rad = ((Circle) o).radius();
//

}
}
}
}