为什么Java没有像C++那样的全局变量?

12
为什么Java中没有全局变量?如果我想在程序的所有类中使用某个变量,怎么办?

10
全局变量最终会带来人类的毁灭...或者至少会毁掉我的桌子、椅子、显示器和头发。 - wheaties
我的头发早就被毁坏了。 - Jasper Blues
10个回答

44

如果你真的想要这么做,可以将它设置为公共静态变量。

然而,建议不要这样做,因为会导致代码不够优雅,难以维护和测试。


8
我作为 Stack Overflow 社区成员已经尽了我的职责,我给 Jon Skeet 点了赞! - Michael Brown
4
Jon Skeet 不需要社区,因为整个宇宙已经给他点了赞。 - Craig Walker
2
Jon Skeet、Jeff Atwood 和 Joel 会付钱让你去谄媚他们吗? - Hai
2
你有幽默感吗? - Valentin Rocher

10

全局变量(在Java上下文中 - public static 变量)是不好的,因为:

  • 难以维护 - 无法设置断点或记录每个变量的更改,因此运行时意外值将非常难以跟踪和修复

  • 难以测试 - 参见Miško Havery 的帖子

  • 难以阅读 - 当有人看到代码时会想知道:

    • 这是从哪里来的?
    • 它还在哪里被调用?
    • 它还在哪里被修改了?
    • 我怎么知道它当前的值?
    • 它在哪里记录了文档说明?

需要澄清一点 - 变量不等于常量。变量会改变,这就是问题所在。因此,拥有一个public static final int DAYS_IN_WEEK = 7 是完全可以的 - 没有人可以更改它。


9
一些有效的全局“变量”其实是常量;-),例如:Math.PI

1
现实生活中,但并不完全相关 ;) - Bozho
4
如果圆周率的值改变了会怎样? - dsimcha
7
那么全局变量将是我们最不用担心的问题。 - Bozho
2
这是一个定义的常量,以防它发生变化。那么只需要在一个地方进行更改,而不是通过替换所有3.0引用为3.22114(或任何它更改为)来进行更改! :-) - Brian Knoblauch
@Brian:请注意,这不是正确的。当它被定义为编译时常量时(我认为它是),在此情况下更改定义不会改变之前编译过的任何内容,因为该值将被内联而不是从此变量读取。 - Joachim Sauer
显示剩余3条评论

7

1
一个恶魔的辩护:静态成员不在对象内部 :) - Nemanja Trifunovic
1
它们属于类,而类本身就是对象。 - danben
4
嗯...我以为它们是丑陋的东西! - CesarGon
好的。我已经调整了它,使用与链接维基百科文章相同的措辞。 - Frank V

5

为什么全局变量很糟糕,在这里有解释。


2

我想补充一下,如果你想使用一个常量全局变量是安全的。要使用它,使用final关键字。例如:

public static final int variable;

2
不要将其分配给可变对象。 - Tom Hawtin - tackline

2
如果您需要从程序的任何部分访问某个特定资源,请查看单例设计模式。 Singleton Design Pattern

4
“Singleton Is Evil”(单例模式是邪恶的)的人已经注意到你了,可能很快就会来敲门。我建议不要回答。 - danben

1

全局变量与面向对象编程不兼容。但是可以将常量作为全局变量。从某种意义上说,singleton 是全局变量。如果您想将常量作为全局变量,则最好使用 enums

编辑:

以前被称为 Class.Constant 的常量现在可以通过使用 static import 来使用 Constant。这尽可能接近 C++ 中的全局变量。


0
package foo;
public class Globals {
  public static int count = 3;
}

然后,您可以在任何地方访问它,如下所示:

int uses_global = foo.Globals.count + 1;


0
Java旨在创建完全可移植、完全可重用的对象。

根据定义,依赖于“全局变量”的东西不是完全可移植或完全可重用的。它依赖于新(重用)系统上存在该全局变量,并且依赖于新(重用)系统上的代码操作该全局变量。此时,最好将该全局变量放入自己的对象中。


1
我能理解可重用性和封装(作为与全局性相反的概念)之间的关系。但是全局性如何与可移植性相关? - CesarGon
@CesarGon:当您将使用全局变量(例如MyBigFatVariable)的对象移植到一个新系统时,如果该系统使用具有相同名称的全局变量来完成完全不同的任务(也许它具有完全不同的类型),会发生什么?(经验丰富的软件专业人员称之为“火车失事”。建议体验此类事件的工具包括一把草坪椅、一箱啤酒、一大盒爆米花和一个良好的观察点。建议在事件发生时远离现场。) - John R. Strohm
好的,我明白了。问题不在于移植本身,而在于将一段代码集成到新环境中。它可能是同一平台上的新环境。可移植性是关于跨平台边界的。因此我感到困惑。但还是谢谢你的解释。 :-) - CesarGon

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