2010-01-17 99 views
46

我讀過Java不支持與C/C++不同的局部變量static。現在,如果我想用一個局部變量編寫一個函數,其值應該在函數調用之間持續存在,那麼我該怎麼做?
我是否應該使用實例變量?如何在Java中創建靜態局部變量?

+0

這就是爲什麼Java需要關閉(開玩笑)。 – 2010-01-17 04:01:40

+0

@darren:閉包與靜態本地人有什麼關係? – missingfaktor 2010-01-17 04:47:43

+9

他希望靜態局部(通過C語言)通過多個函數調用來維護狀態。換句話說,在函數返回後有本地存在。這是關閉的一種用法。 – 2010-01-17 05:21:45

回答

29

您可以有一個靜態類變量,它將保留在類的所有實例中。如果那是你想要的。如果沒有,則使用實例變量,該實例變量只能在該對象的方法調用中保留。

public class Foo { 
    static int bar; 
    //set bar somewhere 

    public int baz() { 
     return 3 * bar; 
    } 
} 
+7

我認爲在大多數情況下*實例變量*應該很好,如果@ gameover想要的是替換方法靜態局部變量。 – bryantsai 2010-01-17 03:40:11

+0

我同意。想要一個非最終的靜態變量是非常罕見的。將ID編號分配給對象是一個例子,但將最後使用的ID編號存儲爲靜態變量。 assignID()返回lastID + 1 – 2010-01-17 03:51:59

+5

@EllieP。 'return lastID ++;' – Cruncher 2013-09-16 15:26:04

4

Should I resort to using instance variables?

是的 - 畢竟,這是實例變量的用途。它們在調用對象的方法之間存儲狀態。有靜態類變量可以達到相同的結果,但可以使您的程序更耦合,更難以測試/模擬/維護。

4

如果你想重用函數調用之間的變量值和隔離等方法這個變量,你應該在一個對象封裝它。首先,定義一個類只有「靜態類」變量和函數,你需要:

class MyFunctionWithState { 
    private int myVar = 0; 
    public int call() { 
     myVar++; 
     return myVar; 
    } 
} 

然後,從您的客戶端代碼:

class Foo { 
    private MyFunctionWithState func = new MyFunctionWithState(); 
    public int bar() { 
     return func.call(); 
    } 
} 

現在如果func依賴於內部狀態Foo您可以通過call()通過相關數據或傳遞的Foo一個實例,讓函數調用相應的干將:

class MyFunctionWithState { 
    private int myVar = 0; 
    public int call(Foo f) { 
     myVar += f.getBaz(); 
     return myVar; 
    } 
} 

class Foo { 
    private MyFunctionWithState func = new MyFunctionWithState(); 
    public int bar() { 
     return func.call(this); 
    } 
    public int getBaz() { /*...*/ } 
} 
+0

爲什麼它必須如此複雜?將static int myVar放入成員函數中是否與java語言或功能的某些部分發生衝突?我不同意這種類型的東西也很少見。也許我需要一些函數來保持變量的狀態,並且我不希望類中的所有其他函數都可以訪問該變量。讓變量更接近它使用的地方要好得多。我想我可以將變量放在函數的上方,但是當其他函數可能使用相同的變量名稱時,仍然會導致混淆。 – user1164199 2015-08-27 15:32:15

+0

當我說「將靜態int myVar放在一個成員函數中與java語言或功能的某個部分衝突嗎?」時,我的意思是「是否可以在未來的java版本中添加此語言功能?」 – user1164199 2015-08-27 15:37:49

5

局部變量是方法內部的變量。只有方法可以訪問這些變量。你不能有一個靜態局部變量,但你可以使用實例變量或類變量。

如果你的方法是靜態的,默認爲所有對象創建一個這個方法的副本,並且不能進一步分解,因爲局部變量限制它們只訪問它們的方法。

-3

final int intVar = 1; //將只插入一次。在方法中表現爲C++靜態局部變量。

+2

這是一個誤導性的答案,因爲在這個例子中'intVar'的行爲就像一個C++靜態局部變量的唯一原因是因爲它被分配了一個常量。例如in void method(int arg){final int intVar = arg; ...},'intVar'不會像C++靜態局部變量。 – 2014-09-05 21:50:31

+0

你不能增加或減少最終變量 – 2015-01-27 14:50:41

-1

在下面的例子count行爲就像一個靜態本地變量,你可能會在C使用:

public class Foo { 

    private int count = 0; 

    public int getCount() { 
     return count++;    
    } 
} 

沒有靜態當地變量,如其他語言的支持。由於Java非常「面向類」,它試圖將其引入到上下文中。如果要模擬該行爲,則使用僅由此方法使用的實例變量。因此,對於不同的方法而言,這是靜態的,而不是該類本身。

+1

單個實例的靜態對我來說聽起來不是靜態的。靜態的主要觀點是A)全局值。不依賴於實例。 B)避免爲每個實例創建一個變量:) – borjab 2015-09-23 11:34:52

+0

@borjab:是的,但由於OP寫道:「現在,如果我想用局部變量編寫函數,其值應該在函數調用之間持續存在,那麼我該怎麼做「......看起來很明顯,這似乎是正確的。靜態在一定程度上取決於上下文:對於這個實例中的函數,它將是「靜態的」......另一方面,常規的「靜態」類在程序的不同實例或甚至不同設備之間不是非常靜態的;-) – Levit 2015-09-23 12:22:22

0

要麼你標記了一個正確的答案,或者你確實需要靜態類變量 - 但正確的答案基本上是萊維特的,或者從技術上來說是所有答案的混合物。

對於像我這樣的C背景的人來說,真正想要靜態函數局部變量純粹是爲了超過全局變量的範圍優勢,似乎答案是你不能在Java中。不是沒有像@paradigmatic這樣的東西,你會得到一個具有靜態全局和getter()的類的實例,它是你正在運行你的函數的類的實例所獨有的。

如果像我懷疑的那樣,像Singleton一樣重新運行這個類,或者像我們開始的最初的程序編程人員那樣完全靜態地執行,@Ellie P或@ user2626445的答案可以正常工作,因爲沒有其他實例會破壞全局。但爲了實現我認爲它應該是實際應該只是一個實例變量,這是一個全局的C語言。它們持續跨越函數調用,但允許您的函數以OO方式使用,因此多個實例可以保持自己的這個特定函數的持久變量。

個人而言,我用jave來解決這個問題,就像我通過在函數聲明之上的文件中聲明全局函數來解決Hi-Tech C不允許函數位變量一樣。那樣我在後來破解代碼時不太可能認爲它是一個全局的東西,並且很容易被它弄糊塗 - 這不就是我們爲什麼要封裝東西嗎?