关于java:为什么静态根据上下文有不同的含义?

Why does static have different meanings depending on the context?

本问题已经有最佳答案,请猛点这里访问。

据我所知:

  • 静态类只适用于嵌套类,这意味着嵌套类没有对外部类的引用。

  • 静态字段有点像全局变量,因为它只有一个实例,并且由同一类的其他成员共享。

  • 静态方法意味着即使对象尚未实例化,也可以调用它。

我正在介绍Java课程,我试图巩固我的知识,并试图找出为什么不同的关键字不被用来表示不同的含义。


您的示例都是正确的,但是它们都有一个共同的特性。static一词意味着不需要封闭实例。

  • 只有静态内部类才能在没有封闭实例的情况下存在。例如,如果您有一个类Foo和一个非静态的内部类Bar,那么您就不能在Foo的实例之外创建Bar的实例。

  • 静态方法意味着您不需要类的实例来调用该方法。例如,您可以调用String.format,而不使用实际的String实例。

  • 即使没有类的实例,静态字段也将存在。如果你的Foo类有一个静态的counter字段,你可以在不实例化Foo类实例的情况下访问它。

考虑一下,作为一个澄清点,一个接口可以有静态类、静态字段和静态方法。但是,它不能拥有任何这些东西的非静态版本(忽略默认方法,这些方法是在概念中特设的)。这是因为您永远无法创建接口的实例,因此永远不会有封闭实例。

您也可以将内部接口、注释和枚举声明为静态的,尽管在这种情况下关键字是完全冗余的(例如,类似于声明接口方法抽象)。接口、注释和枚举与要开始的封闭类没有关系,因此静态类不能真正消除这种关系。

最后一个拜占庭点。如果执行静态导入(import static pack.age.Foo.*操作),则可以对类中的任何静态项(包括接口、注释和枚举,无论它们是否被冗余标记为静态)进行无条件引用。


Why does static have different meanings depending on the context? Why
didn't aren't different key words used?

它其实没有不同的含义。

您可以使用static关键字来指示可能遇到的以下情况:

"without regard or relationship to any particular instance"

  • 静态字段是属于类而不是任何特定实例的字段。

  • 静态方法是在类上定义的,没有任何this的概念。这种方法不能访问任何特定实例中的任何实例字段,除非将实例传递给它。

  • 静态成员类是一个嵌套类,它没有封闭类的概念,并且与封闭类的任何特定实例都没有关系,除非将此类实例传递给它(例如传递给它的构造函数的参数)。


从Cay Horstmann的核心Java:

The term"static" has a curious history. At first, the keyword static was introduced in C to
denote local variables that don’t go away when a block is exited. In that context, the term
"static" makes sense: The variable stays around and is still there when the block is entered
again. Then static got a second meaning in C, to denote global variables and functions
that cannot be accessed from other files. The keyword static was simply reused, to avoid
introducing a new keyword. Finally, C++ reused the keyword for a third, unrelated,
interpretation—to denote variables and functions that belong to a class but not to any
particular object of the class. That is the same meaning the keyword has in Java.


Java继承了C++和C语言。在这些语言中,EDCOX1〔0〕有两个附加的含义。限定为static的局部变量(函数范围)的含义与类中静态字段的含义有些相似。但是Java不支持这种"静态"的上下文。在文件范围内将变量或函数限定为EDCOX1(0),即"SSH"!不要告诉链接器!"Java也不支持EDOCX1 0的这种意思。

在英语中,根据上下文的不同,同一个词可以有多种含义。在字典中查找任何常用词,您将找到该词的多个定义。有些词不仅有多种含义,而且有多种词类。"例如,根据上下文,counter可以是名词、动词、形容词或副词。根据上下文的不同,其他单词可能有相互矛盾的含义。""道歉"的意思是"我很抱歉!"或者可以说"我一点也不抱歉!"后者的一个主要例子是G.H.哈代的"数学家的道歉"。英语在这方面一点也不是唯一的;这同样适用于人类用来相互交流的任何语言。作为人类,我们很习惯于根据上下文来表达不同含义的词语。

在计算机语言中,关键词太少和太多之间存在着固有的冲突。lisp、forth和smalltalk是非常漂亮的语言,只有很少的关键字(如果有的话)。它们有一些特殊的字符,例如Lisp中的左括号和右括号。(完全公开:我已经用这三种语言编程了,而且我很喜欢。)这里有一个问题:祝你在六个月后读到你自己写的代码。更幸运的是,把代码交给别人。因此,这些语言的追随者数量也相当有限。其他语言则高高在上,保留了大量的单词作为"关键字"。(完全公开:我也被迫用这些语言编程,我讨厌这样做。)

计算机语言中关键词太少或太多会导致认知失调。同一个关键字在不同的上下文中有不同的上下文并不是,因为作为人类,我们已经很习惯了这一点。


Java教程说

As with class methods and variables, a static nested class is
associated with its outer class. And like static class methods, a
static nested class cannot refer directly to instance variables or
methods defined in its enclosing class: it can use them only through
an object reference.

基本上,"静态"意味着用它标记的实体与类的实例分离。静态方法没有关联的实例。静态字段在所有实例之间共享(基本上存在于类中,而不是实例中)。静态嵌套类与封闭实例分离。你说得对,这有点令人困惑,因为你可以有一个静态嵌套类的实例,其中包含非静态方法和字段。将单词static想象为"我声明的实体、字段、方法或内部类与封闭实例没有关系"


正如我所看到的,所有提到的static的使用都有一些共性——在所有情况下,它们意味着类/字段/方法与类实例的关联要比不使用static的情况少。当然,静态字段和静态方法之间的等价性应该特别清楚:它们是声明单例(每个类加载器)字段和处理这些字段的方法的方法,与其他语言中的全局对象类似。

也许,对嵌套类使用static的精神并不像使用static那样明显,但它确实共享了这样一个方面,即不需要包含类的实例来使用此构造。

所以我不认为这些是特别不一致的。

对于为什么关键字在编程语言中被重新用于明显不同的目的这一更为普遍的问题的一个答案是,随着语言的发展,通常会引入一些特性——但是添加新的关键字很困难,因为通常会中断可能将其用作标识符的现有程序。例如,Java实际上保留了关键字EDOCX1 10,即使它在语言中未被使用,也可能允许将来扩展。

这种不愿添加新关键字的行为常常导致旧关键字过载。