正在使用NetBeans做一個稍大點的程式,剛剛學習使用,感覺程式中需要用到全域變數(其實java中是沒有全域變數這個概念的)。
在網上查了不少的資料,得到一點點體會:
首先,java中是沒有全域變數這個概念的,java程式中不能像C++那樣在類外定義全域變數,因為JAVA當初出現的初衷就是為了安全性和跨平台性,所以去掉了類似C、C++中的全域變數的概念。JAVA中不應該有所謂全域變數的概念,全域變數嚴重影響了封裝和模組化,所以中需要所謂的全域變數,那一定是對程式的設計出了問題。以上是網上的觀點,但就我目前來說,一個能在全域上使用的變數是有必要的。
第二點,java提供了public static關鍵字來實現一個全域的變數。如果程式只有一個包的話,那麼將這個public static(被聲明為static的變數不需要執行個體化對象即可直接使用類名來引用之) 修飾的變數放到程式初始化的地方去實現,就可以在這個程式的各個地方直接調用這個變數了。這雖然不叫全域變數,但實際使用中和全域變數的意思是一樣的。當然你也可以完全不用全域變數,可以寫一個類,定義一般變數,並為該類定義一些操作變數的方法,通過調用可以更改變數的這些方法來達到使用全域變數的目的。
還有,關於static的用法,static可以修飾變數、方法,也可以修飾類,但是static類只能是內類。
靜態內部類在概念和實現上都十分簡單,基本上來說就是在您的主類中定義一個靜態類:
public class Foo
{
// ....
public static class Test
{
public static void main (String[] args)
{
// ....
}
}
}
說到向您主要的類中添加輔助代碼,其中最重要的一點就是靜態內部類被編譯到一個單獨的 .class 檔案中,這個檔案獨立於它的外部類。例如,如果外部類叫做 Foo,而它的一個內部類叫 Test,那麼這個內部類將被編譯成 Foo$Test.class 檔案。.class 檔案的分離意味著您可以將輔助的嵌套代碼與主要的外部類牢固地捆綁在一起。它們在同一個源檔案中,內部類的確是在外部類的內部。您無需再付出任何發布或運行時的開銷。真棒!例如,如果輔助代碼只是用於調試,那麼您只需發布 Foo.class 檔案而將 Foo$Test.class 檔案留下即可。
我將這個技巧主要用於編寫外部類的示範代碼、錯誤調試代碼,以及進行單元測試實作類別行為的自動驗證。(當然,做為一個勤奮的開發人員,我準備將測試代碼轉化成單元測試。)
注意,要執行 Foo.Test 類的 main() 方法,請使用下面的命令:
% java Foo$Test
如果您正在使用的命令解釋程式(shell)把“$”做為一個保留字,那麼您應該使用下面的命令:
% java Foo//$Test
還有一點十分有趣:靜態內部類根據定義可以訪問外部類的保護域和私人域。這件事可以說既有利也有弊。因為您可能在不經意間就破壞了外部類的保護域和私人域,從而違反了它的封裝性,所以請小心對待!這一功能最恰當的應用就是編寫類的白盒測試程式--因為這樣可以引入一些利用通常的黑箱測試很難引入的問題(黑箱測試不能訪問對象的內部狀態)。
XYPair 類十分簡單。它提供一個固定的整數對,(x,y)。XYPair.Test 類有一個 main() 方法可以對 XYPair 進行簡單的測試並輸出結果。試著調整測試代碼和核心代碼來實驗各種可能的問題。
如果您更加大膽,您可能想檢驗 Java 單元測試構架(JUnit)。您可以去掉原始碼中的各種注釋,然後利用 JUnit 的測試引擎運行這些測試程式。
註:
用Static定義的靜態成員函數或者靜態變數,可以通過其所屬類名來直接調用.為什麼可以這樣?因為既然這個類的所有對象都是使用的這一個變數,那麼理所當然我不需要去從其中的任何一個對象去引用它,而只是通過類名引用就可以了嘛.這樣不是可以方便的實現一些全域函數和全域變數嗎?把所有全域的函數或者全域的變數都定義在一個靜態類中,調用的時候直接通過這一個類名就可以方便的訪問所有的全域變數和全域函數了。
附:
確實全域變數在某些環境下可能還有其實際的意義。但是在JAVA中,確實沒有所謂的全域變數的概念,通過設定一個abstract class or interface,並將許多final or final static field置於其中,並在使用時調用ClassName.xxx or InterfaceName.xxx來類比全域變數的使用(可以肯定的是,在許多的著作中大師們都已經反覆強調了將許多常數放入一個abstract class or interface,並使之成為常數類或常數介面的做法是對此功能的誤用,並不鼓勵如此使用,有興趣可以參閱《effective java》——機械工業出版社出版 Joshua Bloch 著),但
首先,final or final static確實不是全域變數的概念,在JAVA中,一切都是對象,在對象中聲明的無論是field還是method亦或是property都將歸屬於某一種抽象或具體類型,否則也不會在調用中使用ClassName.xxx or InterfaceName.xxx這樣的形式來加以說明這是這個CLASS的XXX,那是那INTERFACE的XXX。事實上final代表的是一種常量形式(Constant),而static則代表一種靜態觀念,常量的概念是為了區別於變數而存在的不變的變數(有些彆扭,突然發現自己詞語貧乏, HOHO),而靜態則是希望區別於某一具體Object而獨立存在於某一特定類型的變數(到可以稱之為該類型的全域變數,但個人感覺不很確切)。全域變數的概念顯然過於寬泛,以至於我們說一個程式甚至是一個系統擁有一個唯一的變數變成可能,但final or static顯然不是為其而設計的(當然可以類比)。
其次,閣下提到的有關於“全虛擬機器只有一份,資料庫連接池對象...”是設計模
式中所謂單例模式的實際應用,該模式確實非常像所謂的全域變數的概念,但設計這樣單個執行個體確實是因為在系統的整個生命週期中只需要一份該執行個體存在的緣故,更多的是突出概念而非實際應用,而全域變數則更多就是為了實際應用而生,這樣就會導致許多不成熟的,不加思考的應用加於其上而導致黏糊的像意大利麵條一樣的代碼。
所以個人認為,依在下實在低微的學識實在不敢胡亂評說關於全域變數是否有實
際意義這樣巨大的課題,這樣的課題還是留給那些專家去討論吧。至於如何實際應用全域變數,我看,還是有則去之,無則加冕吧,實在要用偶也麼的辦法(不過自從使用C++/JAVA開始,全域變數的使用確實降到了一個極低的程度,也許是因為在下的代碼寫的還是太少的緣故吧,呵呵...).(摘自 http//topic.csdn.net/t/20050430/22/3979146.html)