为什么Java中的静态方法只能接受方法内部的final或非final变量,而不能接受静态变量?

3
为什么Java中的静态方法只能接受方法内部的final或非final变量,而不能接受静态变量?
例如,我有以下方法:
public static void myfunc(int somethig)
{                                      
  int a=10;                            
  final int b=20;                      
  static int c=30;   //gives Error why?
}

finalstatic是正交的概念。问题所暗示的三个选项并不存在(或者说不可能存在)。在允许使用静态变量的情况下,无论是静态还是非静态,它们都可以是final或non-final。 - Carl Manaster
5个回答

11

问题是:为什么不行?

考虑一下:静态局部变量意味着什么?

我建议唯一合理的含义是:

public class Foo {
    static int bar = 21;
    public void foo() {
        static int bar = 42;  // static local
        return bar;
    }
}

等价于这个:

public class Foo {
    static int bar = 21;
    private static foo$bar = 42;  // equivalent to static local
    public void foo() {
        return bar;
    }
}

换句话说,(假设的)静态局部变量与稍有不同可见性规则的普通静态属性等效。

Java语言设计者可能考虑过这一点,并决定静态局部变量所提供的真正价值非常有限,因此没有将其纳入语言中(当然,我也会这样投票)。


2
@nixau - 你之所以会想念它们,这说明了你的编程风格。一般来说,避免使用静态变量是一个好的编程风格,当你必须使用它们时,最好使用单例设计模式。 - Stephen C
1
@reinierpost - 不,我不是。静态变量被人们所不赞同的原因与没有静态本地变量无关。这是因为静态变量会导致应用程序重新进入问题、并行性问题、代码重用问题等等。 - Stephen C
@nixau - 显然,你从未不得不重新设计滥用静态变量的代码。这不是一件小事。 - Stephen C
@reinierpost - 不完全是这样。我的意思是如果没用它们中的任何一个,那么重构代码会更容易。记住,这个帖子最开始是我评论@nixau可能过多使用静态变量引起的。也可以看看@fjsj的答案。 - Stephen C
@Stephen C:好的,我理解了你的观点,但这并不是反对静态变量的论据。 - reinierpost
显示剩余7条评论

3
在Java中(在面向对象编程中普遍适用),对象包含状态。方法应该通过对象属性共享状态,而不是通过静态局部变量共享状态。

2

你不能拥有静态局部变量。这没有意义。

但是你可以在你的类中拥有一个静态字段。


资源:


为什么这没有意义呢?既然C++可以做到,那它应该是有意义的。而且这不仅仅是为了与C语言向后兼容。否则,C++只会允许在函数中使用静态局部变量,而不是方法。 - fjsj
1
@fjsj 我不是C++的专家,我的意思是说没有必要使用一些可能难以理解的东西(如运算符重载等)。Java就是这样,它的创建者做出了一些选择,使其尽可能易于理解。 - Colin Hebert
1
说实话,这就像问“为什么Java中没有goto,而C和C++中有goto”一样(我显然夸张了)。 - Colin Hebert
@Colin HEBERT:“它的创建者做出了一些选择,使其尽可能易于理解。” - 这就回答了问题! - fjsj
@Colin Hebert,我个人认为你关于易于理解的说法只适用于该语言的第四版。那个版本没有泛型和疯狂的枚举(但注释还好)。当Java 5发布时,对我来说是一场灾难 - 伟大的库必须由一个糟糕的语言消耗掉。它更多地考虑了C#。它引入的功能明显未能达到前面提到的尽可能易于理解的目标。 - nixau

1

你不能拥有一个静态变量。这样的东西不存在。你可以将一个类变量设置为静态。


-1

由于Java中的每个函数都必须在类内部,因此您可以通过在类中声明字段来获得相同的效果。这是最简单的方法,而且Java语言设计者非常保守。当有更明显且不那么复杂的方法来完成同样的事情时,他们永远不会添加这样的功能。

编辑:我想从哲学上讲,Java中的函数不是第一类的。它们不应该存储数据。类是,并且它们确实存储数据。


这并不是相同的效果:现在类中的所有方法都可以访问该变量。 - reinierpost
1
好的,但我认为在实践中,能够做到这一点是完全无用的,因为如果您可以访问一个函数的源代码,您将能够看到其他函数的代码。通过限制同一类内部函数的访问权限,无法获得封装的任何益处。如果你能看到它,就没有“信息隐藏”。如果这值得一个“-1”,我会以自豪心态接受它 :-)。 - gtrak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接