2010-01-17 100 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不允许函数位变量一样。那样我在后来破解代码时不太可能认为它是一个全局的东西,并且很容易被它弄糊涂 - 这不就是我们为什么要封装东西吗?