java 區域性變數和全域性變數問題
面的輔助線。
如果基於效能的考慮,避免每次呼叫的時候為臨時變數分配空間,就可以將它宣告為成
員變數,例如臨時壓縮緩衝區。
如果基於效能的考慮,避免每次訪問的時候訪問成員變數(尤其在迴圈的時候),就可
以將它宣告為臨時變數。
如果要在避免在函式之間傳遞大量引數,也可以用成員變數來節約引數個數和佔用的空
間 變數可以在任何類中申明,但是邏輯關係要清楚。
我認為同意那個高手的意見.全域性變數是不應該使用的.
在java中也不存在全域性變數的概念.
如果是全域性的就用單例.
全域性變數會導致使用的擴散,無法控制對該變數的呼叫.
而且對於現在的趨勢,硬體的成本遠遠低於軟體的成本.
原來樓主要討論的是變數是應該在方法外宣告還是在方法內宣告 這一點我想的不多,只認為最簡單的原則是: 用來耦合的在方法外宣告,否則一律在方法內部宣告,不必要的存在只會造成不必要的錯誤
面向物件程式設計中,我不習慣再叫什麼‘全域性變數’。而叫類成員。在同一個類當中,只要能夠使用( 不考慮靜態成員和非靜態成員的訪問控制),那就是全域性的,類方法中的引數,是區域性的。 在類中,如果對類成員‘讀’的地方比較多,我覺得設計往往是合理的,如果‘寫’的地方比較多,我建 議儘量做成引數傳遞,然後提供一個公共方法讀取。 靜態成員對於類例項來說,就有點‘全域性變數’的味道了。 Java程式中 ,不能在所有類之外定義全域性變數 ,只能通過在一個類中定
義公用、靜態的變數來實現一個全域性變數。例如 : Class GlobalVar{
public static global_var;
} 在類 GlobalVar中定義變數 global_var為 public stat-ic,使得其它類
可以訪問和修改該變數。 =========================================
這是全域性變數的定義,如果有可能的話,儘量使用區域性變數為好
“private HashMap hm;//呵呵,我稱此種為全域性變數” 其實,“全域性”與“區域性”也是相對而言的,相對於類的內部,可以認為是“全域性”的。相對於其它的類 ,也可以認為是“區域性”的。如果某一private變數擁有getter或/和setter,我們還可以稱之為“屬性” 。 我覺得,在程式設計實踐中,用哪一種方式,完全是根據實際需要而定。不應象樓主說的那位“高手”那樣做 強制的要求。 還有一點,面向物件的思想強調的是“物件和物件的有機聯絡”,那麼,一個類中如果就只有方法,那麼 跟以前面向過程程式設計一樣了嗎?這樣做是不是違背了面向物件的初衷呢?
> >
錯了,其實不完全是這樣的。因為很有可能這個類本身的存在,就是面向物件的一個部分。比如,俺給你 舉一個簡單的例子來說明吧:
一個配置載入的類比如說ConfigLoader從配置檔案中載入配置資訊,配置可能是這樣的nv對:
name : value.
作為客戶來說,並不需要關心這個value是什麼,可能只是需要根據這個value創建出來的一些結果,比如 配置類名通過反射機制來建立就可以了。
那麼通常ConfigLoader這麼做:假設使用HashMap來儲存:
final Map map = new HashMap();
// ... 讀取配置檔案的記憶體
for(each:...) {
String name = each.getName();
String value = each.getValue();
Object actualValue = build(value);
map.put(name, actualValue);
}
Object build(String value) {...}
// ..
這樣是一種通常的做法,但是如果細了說,ConfigLoader這個類實際上有兩個職責了:
(1) 載入配置檔案。
(2) 根據指定的value來構建物件例項。
可能會導致的問題是,第一構建方法的變化會導致ConfigLoader這個不相關的類的修改,第二,對單元測 試增大了難度,至少看起來不是一個優美可測的結構。 因此,在這樣的情況下,就可以把構建的內容單獨抽離到一個新的物件中去做:
class Builder {
Object build(String value) {...}
}
剛才的程式片斷就簡單變為:
map.put(each.getName(), new Builder().build(each.getValue());
這樣,即便構建的邏輯發生變化,對於ConfigLoader來說是沒有任何影響的。 樓主可以看看比如Builder這個類,它本身沒有任何變數,就是提供了一個build的方法。。但是它本身就 是體現了面向物件的一個部分,它承擔了構建這個責任。 =================
另外,也有變成面向過程的程式設計,通常就是俺們經常使用的工具類,就是做的面向過程的事情。
final public class Utils {
private Utils() {}
public static void someMethod(...) {...}
}
這個someMethod就是一個典型的面向過程的東西。
當然要記住,這樣的寫法並不是完全不可取的。。在需要的場合,很大程度上這樣是一個不錯的解決方式 。
再說了,我經常看到有類似下面的宣告: public class Test{
private String s;
protected HashMap hm;
private List list;
public ... ...
public Test(){
s = "test ";
hm = new HashMap();
list = new ArrayList();
... ...
}
} 可以這麼說,凡是在構造方法中建立的變數都是這種意義上的區域性變數,那就是說,如果其為非private的 話,那麼是提供給別的類訪問用的,是可以宣告為這種意義上的全域性變數的,那麼如果是private的話,那 麼本就不應該這麼去建立和宣告???而應該儘可能得把它放在區域性去宣告和建立,應用的時候,靠方法 的引數和返回值來通訊????
jvm對於記憶體資源的回收需要等待一個collection週期,而不是實時回收。
如果對一個變數的使用率頻繁建議使用全域性。可以節省CUP分配記憶體空間的時間。
如果使用區域性變數。雖然在整個程式執行期記憶體資源消耗減少。可是CUP要花更多時間用在記憶體資源分配上 。
過去,使用面向過程的程式設計方法時,時常討論“區域性變數”和“全域性變數”的問題。 早期(20世紀80年代或更早)沒有結構化程式設計思想或方法時,變數都是“全域性”的,即整個程式可以訪 問到每一個變數。 後來(20世紀80年代至90年代),有了結構化程式設計思想,程式設計師們就覺得,哎呀,用區域性變數怎麼能行 呢?全域性變數多好呀,程式想怎麼寫就怎麼寫,有了一個變數,想在哪用就在哪用,想怎麼用就怎麼用。 可是,沒過多久,思想轉變了,程式設計師們又覺得,還是少用全域性變數好呀!你看,我們寫的程式,結構多 麼清晰呀,讀來就象一股清泉,簡直就是一部藝術作品呢! 現在,我們採用的是面向物件的思想和方法!全域性變數在哪裡呢?根本就沒有嘛。我們只有被稱作“類成 員”的東西! “類成員”可以稱為“全域性變數”嗎?姑且稱之。且慢!如果是private的,還能稱之為“全域性變數”嗎? 好,好,就算它們全部是public的,是否所有的資料全都要由“類成員”保管嗎?如果是的話,我們應該 考慮一下,就與“面向物件”的思想可能就是背道而馳的了。
謝謝上面的朋友們: 我說的全域性變數就是指同時有幾個方法都要用到的變數,這些變數可以說會經常被使用,方法可以基於它 們進行通訊,我覺得如果要是寫成區域性變數的話,那麼很多方法都會有入參和返回值,這樣不便於閱讀和 理解程式碼啊 在上面,大家異口同聲得回答區域性變數,原因基本上是: 1.資源消耗少
2.最少通訊原則 我也同意這點,但是這和“類內部強耦合”相沖突,希望多討論討論這方面~~~~~~ 再一個,對於“2.我們寫的類到時候要被多執行緒呼叫的,所以區域性變數更好一點”這一點,我的想法是:
“變數是全域性的還是區域性的,和多執行緒呼叫並無關係,到時只要在總方法上加上synchronized就
好,而且,即使變數是區域性的,要是多執行緒呼叫時,也得加上同步不是?” 也請在這一點上多發言~~~~~~~~
再次謝謝大家的發言~
區域性變數是避免多執行緒造成變數非同步操作錯誤的有效措施 越小域的變數越安全,當一個變數超出它所應用的範圍後,他剩餘的時光只是浪費資源和造成錯誤 區域性變數是避免多執行緒造成變數非同步操作錯誤的有效措施 越小域的變數越安全,當一個變數超出它所應用的範圍後,他剩餘的時光只是浪費資源和造成錯誤
要看那種情況,假如你的這個變數是作為迴圈體內使用,那麼用“全域性”吧,如:
Student student=null;
for(Iterator iter=datas.iterator();iter.hasNext();){
student=(Student)iter.next();
}
這樣可以節約時間,不用沒一次迴圈都要在棧中申請空間以儲存引用;
假如是在類一級的,比如作為類的屬性還是方法的變數,原則是假如方法的引數不是很多的話,那麼採用方法傳遞,樓主也說了,可以採用多執行緒或是池。
使用java也有兩年了,以前是用區域性變數多一點,後來自己體會到,還是全域性變數更能體現面向物件的思想:類的內部應該體現強耦合性,類和類之間應該體現弱耦合性;再說了,每個類要是隻是方法堆砌出來的,也沒有意思了。 但是近來,和一個高手做專案,他卻要求除過把幾個不太變化的物件宣告為全域性變數外,其它的變數都是用區域性變數,我們這個專案比較龐大一點,他的理由是:
1.全域性變數始終佔用記憶體,多了一筆開銷
2.我們寫的類到時候要被多執行緒呼叫的,所以區域性變數更好一點 我覺得,使用全域性變數和使用區域性變數相比,記憶體好像是多佔用了一點,但是不會造成記憶體不足,
而且,變數是全域性的還是區域性的,和多執行緒呼叫並無關係,到時只要在總方法上加上synchronized就
好,而且,即使變數是區域性的,要是多執行緒呼叫時,也得加上同步不是?
很久之前就開始遵循一個原則:變數的最小作用域原則。
即是儘量不要擴大一個變數的可見範圍。