2009年5月13日 星期三

Practical Java Programming Language Guide-第一章 一般技術

第一章‧一般技術


裡面介紹了java通用的一般知識

case 1:引數以by value而非by reference的方式傳遞
某些人誤認Java沒有指標,其實該說java所有物件都是指標,他傳參數全部都以call by value的方式在傳遞,而由於物件以指標的形式被傳入,所以函式內的變數是可以修改傳入的實體
舉個簡單的例子

class Message{
String msg;
public Message(){msg="default"}
}
...
static void f(Message m){m.msg="function"}
...
Message _m=new Message();
f(_m);
System.out.println(_m.msg);

他會印出function,因為函式的m與傳入的_m是指到同一記憶體

case 2:對不變的Data和Object reference使用final
簡單來說就是用final這個修飾子保護變數,但是有一點要注意的
裡面提到儘管用final保護Object reference也只能保護他實體不變而非實體不被改變
用上面的Message類別舉個例子

final Message im=new Message();
im.msg="change";
System.out.println(im.msg);//印出change

im=new Message();//編譯失敗,final object不能重新指向新實體

要改讓object內容不可改,必須用一些編程的技巧讓他成為immutable

case 3:預設情況下,所有non-static的函式都可以被覆寫
簡單來說,只有被加上的final的函式是不能被override的

case 4:在arrays和Vectors之間慎重選擇
一張表格說明一切






















支援基本型別 支援物件 自動改變大小 速度快
array
Y
Y
N
Y
vector
N
Y
Y
N

簡單來說,想要速度快就該用array,想要size可變則選擇vector的相關家族

case 5:多型(polymorphis)優於instanceof
這個case是說比起用inststanceof判斷是哪個類別來做哪些事,不如用多型的技巧更為優雅
這在重構(Refactoring)裡面也有許多相似的技巧


class Parent...
class A extends Parent..

class B extends Parent..

void f(Parent p)
{
if(p instanceof A)//do something
if(p instanceof B)//do something
}//這不是好作法

class Parent{
void doSomething(){...}
}
//假設A,B已經實作doSomething
void f(Parent p)
{
p.doSomething();
}
...
A childe=new A();
f(child);
//使用多型的技巧自動決定函式的行為

這邊題外話一下,在C++的時候只有reference跟pointer才能做到多型
但是在java每個object都可以看作pointer,所以他可以更輕易達到多型

case 6:必要時才使用instanceof
這邊主要是說在逼不得已的時候才使用instanceof,像是使用了Vector,物件全部被轉型成Object(現在的java類似的容器類別大概都有提供樣版<T>,大概也沒機會用到了)

Vector v=new Vector();
v.add(new A());
Object o=v.get(0);//vector的get會傳回Object
if(o instanceof A)//do something

類似如上的狀況,除非物件已經被轉型成我們無法掌握或是無法使用多型的情況才使用instanceof,而上面也提到,java現在的版本大概都有提供樣版可以使用,這情況更少見了

case 7:一旦不需要object reference就將他設為null
這個case是說用不到的object就將他設為null,因為JVM的GC必須所有的instance都不再有reference才會去回收那塊記憶體,如果用不到而又不回收就會造成memory leak
也就是系統無法回收卻又無法使用的記憶體區塊會越來越多造成系統當機

沒有留言: