繁体   English   中英

无法在静态方法中声明静态变量

[英]Unable to declare static variable inside of static method

class Foo {
    public Foo() { }
}

class Bar {
    static Foo foo = new Foo(); // This is legal...

    public static void main(String[] args) { 
        static int a = 0; // ... But why this is not?
    }
}

为什么我们不能在静态函数内部声明静态变量?

您必须使 static final static或删除static

在 Java 中,静态意味着它是一个类的变量/方法,它属于整个类但不属于其某些对象之一。 这意味着 static 关键字只能在“类范围”中使用。

通常,在 C 中,您可以静态分配局部范围的变量。 不幸的是,这在 Java 中并不直接支持。 但是您可以通过使用嵌套类来达到相同的效果。

例如,下面是允许的,但它是糟糕的工程,因为 x 的范围比它需要的要大得多。 此外,两个成员(x 和 getNextValue)之间也存在不明显的依赖关系。

static int x = 42;
public static int getNextValue() {
    return ++x;
}

一个人真的很想做以下事情,但这是不合法的:

public static int getNextValue() {
    static int x = 42;             // not legal :-(
    return ++x;
}

但是你可以这样做,

public static class getNext {
    static int x = 42; 
    public static int value() {
        return ++x;
    }
}

它是以牺牲一些丑陋为代价的更好的工程。

其他人已经解释了如何在编码级别处理这个问题。 请允许我解释为什么方法中的静态没有意义的逻辑和哲学原因。 您必须问“您希望变量持续多长时间?”的问题。

  • 普通成员变量的持续时间与它们所属的实例一样长;
  • 在方法中声明的变量一直持续到方法退出;
  • 静态类变量在类的生命周期内持续(即对于大多数用途来说是永远的)

那么,您希望“方法内的静态”变量持续多长时间? 如果一直到方法结束,那么您可以直接使用它而不使用静态。 如果是在类的生命周期内,则可以将其声明为静态成员变量。 还有哪些其他选择?

C++ 允许在方法中使用静态,但它们最终的行为就像静态类变量一样,但范围缩小了。 即使在 C++ 中,它们也很少使用。 它们最终也完全像静态成员变量一样存储。 该模式被广泛认为是危险和令人困惑的,因为它使方法“记住”从一次调用到另一次调用的局部变量的值 - 如果其他代码选择该值,该值将被更改在两次调用之间执行该方法。

Java 设计者认为,少量的好处不值得语言的额外复杂性。

将变量声明为最终变量,而不是静态变量。

静态意味着每个类有一个,而不是类的每个实例一个。 Final 表示创建后无法修改。 (尽管请注意,使引用最终不会使其引用的类不可变)。

换句话说,如果你有一个

final String[] array = new String[3];

您不能再更改该变量,例如,如果您想为其分配一个大小不同的新数组,则无法更改。 但是,您可以修改数组的内容。

array[0] = "test";

因为这会修改内容,而不是数组本身。

同样的事情也适用于任何可变对象。

Java 不允许用户在本地创建静态变量,因为在 Java 中静态变量的范围是全局的(即在整个程序中),因此没有必要在本地创建静态变量,因此为了避免歧义,Java 不允许用户创建静态变量局部变量。 我们只能创建静态变量作为全局静态变量。

我想您的期望是像 C 函数中带有初始化程序的static局部变量一样的行为,它只初始化一次,即在函数的第一次调用中,而不是在后续调用中。

Java static字段类似于 C static局部变量,因为静态字段仅初始化一次,即在加载类时。

关于提到它的其他答案, final与此无关 final表示变量/字段的值在初始化后不能更改。

Java 中惯用的解决方案首先不使用static字段,除了常量和诸如缓存和注册表之类的东西。

通常,更好的解决方案是编写一个新类,而不是保存您希望作为常规(非静态)字段保留在“ static ”变量中的值。 您可以在字段声明或新类的构造函数中对其进行初始化,然后在(非静态)方法中进行您想要进行的计算。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM