如何在 Java 中创建静态局部变量?

Posted

技术标签:

【中文标题】如何在 Java 中创建静态局部变量?【英文标题】:How do I create a static local variable in Java? 【发布时间】:2011-01-05 23:52:21 【问题描述】:

我读过 Java 不支持 static 与 C/C++ 不同的局部变量。现在,如果我想用一个局部变量编写一个函数,它的值应该在函数调用之间保持不变,我该怎么做? 我应该求助于使用实例变量吗?

【问题讨论】:

这就是 Java 需要闭包的原因(开玩笑)。 @darren : 闭包与静态局部变量有什么关系? 他希望静态局部变量(在 C 意义上)通过多个函数调用来保持状态。换句话说,函数返回后存在局部变量。这是闭包的一种用法。 TL;DR 回答:你不能。创建包含类的静态成员变量。 这个线程的部分困惑是“静态”关键字在 C 和 Java 中的工作方式不同。在 C 语言中,如果在函数内部使用,该变量的状态从一次调用到下一次调用都会保留,但仅在该函数内部具有作用域。 Java 没有等效的关键字,但一些答案正确地描述了如何使用对象来模拟这种行为。 【参考方案1】:

您可以拥有一个静态类变量,该变量将保留在该类的所有实例中。如果那是你想要的。如果没有,请使用实例变量,该变量只会在此对象的方法调用中保留。

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

   public int baz() 
      return 3 * bar;
   
 

【讨论】:

我认为在大多数情况下 instance variables 应该没问题,如果 @gameover 想要的是替换方法静态局部变量的东西。 我同意。想要一个非最终的静态变量是非常罕见的。将 ID 号分配给对象就是一个示例,不过 - 将最后使用的 ID 号存储为静态变量。 assignID() 返回 lastID+1 @EllieP。 return lastID++; 为防止混淆,您可能希望限制自己对静态方法使用静态变量,对实例方法使用实例变量。对于具有静态功能的实例方法,将该功能封装在从实例方法调用的静态方法中。 它在 ideone error: illegal start of expression 中给出错误【参考方案2】:

如果你想在函数调用之间重用变量值并将这个变量与其他方法隔离,你应该将它封装在一个对象中。首先,定义一个只包含“类静态”变量和所需函数的类:

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 的实例并让函数调用适当的getter:

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()   /*...*/  
 

【讨论】:

为什么要这么复杂?将 static int myVar 放在成员函数中是否与 Java 语言或功能的某些部分冲突?我也不同意这种类型的东西很少见。也许我需要一些函数来保持变量的状态,并且我不希望类中的所有其他函数都可以访问该变量。让变量更靠近它的使用位置会更好。我想我可以将变量放在函数的正上方,但是当其他函数可能使用相同的变量名时,这仍然会导致混淆。 当我说“在成员函数中放置静态 int myVar 是否与 Java 语言或功能的某些部分冲突?”时,我的意思是“是否有可能在未来的 Java 版本中添加此语言功能?”【参考方案3】:

局部变量是方法内部的变量。只有方法才能访问这些变量。不能有静态局部变量,但可以使用实例变量或类变量。

如果您的方法是静态的,默认情况下会为所有对象创建此方法的副本,并且不能进一步分解,因为局部变量将它们的访问权限限制为仅访问它们所在的方法。

【讨论】:

【参考方案4】:

我应该求助于使用实例吗 变量?

是的 - 毕竟,这就是实例变量的用途。它们存储对象方法调用之间的状态。拥有静态类变量可以达到相同的结果,但会使您的程序更加耦合并且更难测试/模拟/维护。

【讨论】:

【参考方案5】:

在以下示例中,count 的行为类似于静态 本地 变量,您可以在 C 中使用:

public class Foo 

   private int count = 0;

   public int getCount() 
       return count++;               
   
 

没有像其他语言支持的静态本地变量。由于 java 是非常面向“类”的,它试图将它带到那个上下文中。如果要模拟该行为,请使用仅由该方法使用的实例变量。所以这对于不同的 method 调用是静态的,而不是类本身。

【讨论】:

单个实例的静态对我来说听起来不是很静态。 static 的重点是 A) 类中的全局值。不依赖于实例。 B) 避免为每个实例创建一个变量 :) @borjab:是的,但既然 OP 写道:Now if I want to code a function with a local variable, whose value should persist between function calls, how do I do that? ... 用显而易见的答案来回应似乎是正确的。静态在某种程度上取决于上下文:对于此实例中的函数,它将是 static ... 另一方面,常规的 static 类在程序的不同实例甚至不同的设备中并不是非常静态的;-) 【参考方案6】:

要么您标记了一个不正确的正确答案,要么您实际上想要静态类变量 - 但正确的答案基本上是 Levit 的,或者从技术上讲是所有答案的混合。

对于像我这样具有 C 背景的人来说,真正想要静态函数局部变量纯粹是为了在范围上优于全局变量,答案似乎是你不能在 Java 中。并非没有做类似@paradigmatic 之类的事情,而是使用具有静态全局和getter() 的类的实例,该类实例对于您正在运行您的函数的类的实例是唯一的。

如果,正如我所怀疑的那样,您将课程作为单例运行,或者完全像我们都开始的原始程序程序员那样完全静态地运行,@Ellie P 或@user2626445 的答案会很好,因为没有其他实例会搞砸提升你的全球。但是要实现我认为的你想要的,它实际上应该只是一个实例变量,它在 C 中是一个全局变量。它们在函数调用中持续存在,但允许你的函数以 OO 方式使用,因此多个实例可以保留它们自己的此特定函数的持久变量。

就个人而言,我通过在函数声明上方的文件中声明全局变量来解决这个问题,就像我绕过 Hi-Tech C 不允许函数位变量一样。这样,当我以后修改代码时,我就不太可能认为它是一个全局的并且很想弄乱它——这不就是我们封装事物的原因吗?

【讨论】:

【参考方案7】:

免责声明:仅仅因为你可以,并不意味着你应该

虽然 Java 不支持静态局部变量,但在最新版本的 Java 中很容易模拟。从 Java 16 开始,可以在方法中创建具有可变静态字段的本地类。随后,您可以像在 C/C++ 中一样改变本地类的静态字段。

public class Main 

    public void foo() 
        class Local 
            static int count = 0;
        
        Local.count++;
    
    

在 Java 16 之前,本地类只能包含静态常量。

【讨论】:

【参考方案8】:

最终 int intVar = 1; // 只会被初始化一次。在方法中表现为 C++ 静态局部变量。

【讨论】:

这是一个误导性的答案,因为intVar 在此示例中表现得像 C++ 静态局部变量的唯一原因是因为它被分配了一个常量。例如在void method(int arg) final int intVar = arg; ... 中,intVar 的行为将不像 C++ 静态局部变量。 你不能增加或减少最终变量

以上是关于如何在 Java 中创建静态局部变量?的主要内容,如果未能解决你的问题,请参考以下文章

在 javascript 中创建一个局部变量来跟踪日历上的月份。

java中静态成员变量、实例变量、局部变量何时创建、何时销毁?

java 程序代码的优化

实例局部静态变量(java)

java 局部静态变量在多线程环境下是不是有线程安全问题??

如何以编程方式将 Java CDI 托管 bean 注入(静态)方法中的局部变量