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

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

【问题讨论】:

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

标签: java scope static


【解决方案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++ 静态局部变量。
          • 你不能增加或减少最终变量
          猜你喜欢
          • 1970-01-01
          • 2011-01-29
          • 2013-09-04
          • 1970-01-01
          • 2018-04-18
          • 1970-01-01
          • 1970-01-01
          • 2021-03-20
          • 1970-01-01
          相关资源
          最近更新 更多