1. 程式人生 > >java 區域性變數和全域性變數問題

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就
好,而且,即使變數是區域性的,要是多執行緒呼叫時,也得加上同步不是?
很久之前就開始遵循一個原則:變數的最小作用域原則。
即是儘量不要擴大一個變數的可見範圍。

相關推薦

java 區域性變數全域性變數問題

所謂臨時變數,就是為了方便起見申明的變數,存放一些中間結果。有點像中學幾何裡 面的輔助線。 如果基於效能的考慮,避免每次呼叫的時候為臨時變數分配空間,就可以將它宣告為成 員變數,例如臨時壓縮緩衝區。 如果基於效能的考慮,避免每次訪問的時候訪問成員變數(尤其在迴圈的時候),

Python-13-函式_02_區域性變數全域性變數

1 """ 2 # 1、區域性變數和全域性變數 3 4 在子程式中定義的變數稱為區域性變數,在程式的一開始(程式碼前面沒有縮排)定義的變數稱為全域性變數。 5 全域性變數作用域是整個程式,區域性變數作用域是定義該變數的子程式。 6 當全域性變數與區域性變數同名時: 7 在定義區域性變數的

T-SQL 區域性變數全域性變數

區域性變數 1 use StudentManageDB 2 go 3 --宣告學號變數 4 declare @stuid int,@stuname varchar(20) 5 6 --查詢李銘的資訊 7 set @stuname='李銘' 8 select StudentId,Stu

SQL中的區域性變數全域性變數

在SQL中,我們常常使用臨時表來儲存臨時結果,對於結果是一個集合的情況,這種方法非常實用,但當結果僅僅是一個數據或者是幾個資料時,還要去建一個表,顯得就比較麻煩,另外,當一個SQL語句中的某些元素經常變化時,比如選擇條件,(至少我想)應該使用區域性變數。當然MS

區域性變數全域性變數,以及作用範圍

       在寫工程檔案的時候,犯了一個基礎性的錯誤,基礎不牢,地動山搖。所以通過查閱資料回顧了一些相關知識,並記錄下來。防止以後再發生這種慘案。 變數按儲存區域分:全域性變數、靜態全域性變數和靜態區域性變數都存放在記憶體的靜態儲存區域,區域性變數存放在記憶體的棧區。

關於區域性變數全域性變數的儲存空間大小問題

下午做最長公共子序列的時候遇到的問題,問了felix後恍然大悟...看程式碼 #include <stdio.h> int main(){ int a[1000000];//區域性變數 return 0; } 編譯執行後發現溢位錯誤。 #include &l

有關 陣列作為函式引數 & 區域性變數全域性變數及其應用

一、陣列blabla 1.0陣列元素作函式實參。 (1).陣列元素可以用作函式實參,但不能是形參。(給陣列分配的儲存單元是連續的) 2.0一維陣列名作函式引數。 (1)陣列元素作實參時,向形參變數傳遞的時陣列元素的值。 陣列名作實參時,向形參傳遞的時陣列首元素的地址。

python 函式的區域性變數全域性變數 global

本文轉載自http://blog.csdn.net/mldxs/article/details/8559973 侵刪 當你在函式定義內宣告變數的時候,它們與函式外具有相同名稱的其他變數沒有任何關係,即變數名稱對於函式來說是 區域性 的。這稱為變數的 作用域 。所有變數的

C語言中區域性變數全域性變數變數的儲存類別(static,extern,auto,register)

C語言中區域性變數和全域性變數變數的儲存類別(static,extern,auto,register) 1----區域性變數和全域性變數 在討論函式的形參變數時曾經提到,形參變數只在被呼叫期間才分配記憶體單元,呼叫結束立即釋放。這一點表明形參變數只有在函式內才是有效的,離開該函式就不能再使用了。

python基礎之四種函式型別、函式的巢狀呼叫、函式的區域性變數全域性變數

函式根據有沒有引數,有沒有返回值,可以相互組合,一共有4種 * 無引數,無返回值 * 無引數,有返回值 * 有引數,無返回值 * 有引數,有返回值 <1>無引數,無返回值的函式此類函式,不能接收引數,也沒有返回值,一般情況下,列印提示燈類似的功能,使用這類的函式 def pr

jmeter多執行緒併發時,區域性變數全域性變數的區別

1. 業務場景5個使用者登入系統,需要將登入介面A返回的token作為介面B的入參。介面B設定集合點,同時請求後臺介面。2. 指令碼2.1  目錄結構                2.2  多個使用者資訊獲取                採用csv檔案儲存使用者資訊   

python 區域性變數全域性變數 global

當你在函式定義內宣告變數的時候,它們與函式外具有相同名稱的其他變數沒有任何關係,即變數名稱對於函式來說是 區域性 的。這稱為變數的 作用域 。所有變數的作用域是它們被定義的塊,從它們的名稱被定義的那點開始。 #!/usr/bin/python # Filename:

JNI區域性變數全域性變數引用

1.區域性變數引用 定義在本地方法內的區域性變數,會隨著方法呼叫完return後,區域性變數也會隨著被釋放。 所以,不要在本地方法中定義static變數來儲存資料!舉個栗子: 像上面這樣子是

python 類中變數 區域性變數全域性變數

1.類中初始化變數 class dig():     def __init__(self,x,y):         self.x=x         self.y=y     def pd(self

python 區域性變數全域性變數 global

當你在函式定義內宣告變數的時候,它們與函式外具有相同名稱的其他變數沒有任何關係,即變數名稱對於函式來說是 區域性 的。這稱為變數的 作用域 。所有變數的作用域是它們被定義的塊,從它們的名稱被定義的那點開始。 #!/usr/bin/python # Filename:

區域性變數全域性變數在記憶體中的儲存位置

靜態儲存方式:是指在程式執行期間分配固定的儲存空間的方式。 動態儲存方式:是在程式執行期間根據需要進行動態的分配儲存空間的方式。 使用者儲存空間可以分為三個部分: 1)程式區; 2)靜態儲存區; 3)動態儲存區; 全域性變數全部存放在靜態儲存區,在程式開始執行時給全域性

區域性變數全域性變數的初始化

寫程式碼的時候遇到了這個問題,選兩段抄過來做個筆記。定義區域性變數,其實就是在棧中通過移動棧指標來給程式提供一個記憶體空間和這個區域性變數名繫結。因為這段記憶體空間在棧上,而棧記憶體是反覆使用的(髒的,上次用完沒清零的),所以說使用棧來實現的區域性變數定義時如果不顯式初始化,

區域性變數全域性變數的差別

全域性變數、靜態全域性變數、靜態區域性變數和區域性變數 全域性變數、靜態變數如果沒有手動初始化,則有編譯器初始化為0。 區域性變數是編譯器永遠不會初始化的變數,如果沒有手動初始化,區域性變數的值為隨機值。 在函式內使用全域性變數,一般應做全域性變數說明,只有在函式內

關於ArrayList儲存區域性變數全域性變數的易錯筆記

       物件的宣告放在棧記憶體,在例項化物件的時候,會在堆記憶體開闢一個記憶體,然後把這個記憶體的地址交給物件。這個就是物件的宣告和例項化過程。  (一)關於使用ArrayList儲存全域性

C語言中區域性變數全域性變數解釋

區域性變數 :   在一個函式內部定義的變數是區域性變數,它只在本函式範圍內有效,也就是說只有在本函式內才能使 用它,在此函式外是不能使用這些變數的。這些稱為區域性變數。   說明     (1)  不同函式中可以使用相同名字的變數,它們代表不同的變數,互不干擾。