56

This question already has an answer here:

As I understand it:

  • A static class only applies to nested classes, and it means that the nested class doesn't have references to the outer class.

  • A static field is kind of like a global variable, in that there is only one instance of it, and it is shared by other members of the same class.

  • A static method means that it can be called even if the object hasn't been instantiated yet.

I am taking an introduction to Java course and am trying to cement my knowledge, as well as trying to figure out why different keywords weren't used to signify different meanings.


  • Anyway don't take the names static class/field/method as standard nomenclature of OOP. For example in python you'd call a java's static method a class method, and there exist static methods which are a different thing. As the answer says in java the static means it's something related to the class but not to its instances. - Bakuriu
  • You don't want to introduce too many keywords into a language. Set aside the issues of the pioneers (each keyword making the compiler executable bigger and the compile slower), every keyword means one probably useful identifier less for the user. (Point in case, I am working with a domain specific language where input is a reserved keyword. That is a pain, I tell you.) So, when similar things are to be achieved in different contexts, re-using a keyword is a valid option. - DevSolar
  • From a reasonable point of view, those all really do the same thing: take a thing and change its scope from instance to class. C and C++ are where static is really overloaded. - Kevin
  • I removed the "why not different words" question from the title to clarify that this question isn't asking about the language designers' intent, but is really just asking "What does static mean, really?" I think it's a great question that demonstrates good understanding of the language -- most Java programmers would never think to ask this, just treating static as a magic word. - Jeffrey Bosboom
  • @user1803551 The question may be the same but I believe the answers in this question are superior to the ones in your link - stanek

6 답변


70

Your examples are all correct, however, they all share a common feature. The word static means that an enclosing instance is not necessary.

  • Only a static inner class can exist without an enclosing instance. For example, if you have a class Foo and a non-static inner class Bar then you cannot create an instance of Bar outside an instance of Foo.

  • A static method means you do not need an instance of the class to call the method. You can call String.format without an actual String instance for example.

  • A static field will exist even without an instance of the class. If your Foo class has a counter field that is static you can access it without ever instantiating an instance of the Foo class.

Consider, as a clarifying point, that an interface can have static classes, static fields, and static methods. However, it cannot have the non-static version of any of those things (ignoring default methods which are sort of ad-hoc'd into the concept). This is because you can never create an instance of an interface so there could never be an enclosing instance.

You can also declare inner interfaces, annotations, and enums to be static although the keyword in that case is entirely redundant (e.g. similar to declaring an interface method abstract). Interfaces, annotations, and enums have no relationship to an enclosing class to begin with so static can't really take that away.

One last byzantine point. If you do a static import (import static pack.age.Foo.*) you will be able to make unqualified references to any static items in a class (including interfaces, annotations, and enums regardless of whether or not they are redundantly marked static).


  • s/variable/class/ in the third bullet point? - immibis
  • @immibis thanks - Pace

19

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

It doesn't really have different meanings.

You can take the static keyword to indicate the following wherever it may be encountered:

"without regard or relationship to any particular instance"

  • A static field is one which belongs to the class rather than to any particular instance.

  • A static method is defined on the class and has no notion whatsoever of this. Such a method can access no instance fields in any particular instance, except when an instance is passed to it.

  • A static member class is a nested class that has no notion of its enclosing class and has no relationship to any particular instance of its enclosing class unless such an instance is passed to it (such as an argument to its constructor).


  • While the general meaning of the answer is correct, I can't agree to some particular parts. "Such a method can access no instance fields in any particular instance, except when an instance is passed to it as a parameter." - no, it can access an instance it creates (classic factory) or one it gets from a static variable (classic singleton). Same stuff with your next bullet point - "unless such an instance is passed as a parameter to its constructor." - yeah, or any other way one can set a variable, including setter methods, DI, static fields, etc. - Ordous
  • " no, it can access an instance it creates (classic factory) or one it gets from a static variable " .. different way of saying the same thing, I would say. An instance created is not an instance that has a pre-existing relationship with a static method. While I won't disagree with the spirit of your rebuttal, neither would I say that it contradicts any of that which had been posted. - scottb
  • "A static field is one which belongs to the Class object" - no, it does not belong to the Class object. Same for methods. - immibis
  • @immibis: I can't disagree, though I would say that that understanding is a useful conceptual model for making the distinction. Today must be the day for semantic precision. I've edited away the references to the Class object entirely. - scottb

16

From Core Java by Cay Horstmann:

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.


  • I disagree with what the quote says about the C and C++ "static" having several unrelated interpretations. One thing all of them have in common is that the memory address of the variable or function is in some way fixed. I think this corresponds well to the Java meaning. - Thomas Padron-McCarthy
  • @ThomasPadron-McCarthy: Yes, but the second meaning in C doesn't really have anything to do with that, since the address of a global variable or function is fixed regardless of 'static'. - Sebastian Reichelt

9

Java inherits from C++ and C. In those languages, static has two additional meanings. A local variable (function scope) qualified as static has meaning somewhat similar to that of a static field in a class. Java however does not support this context of "static". Qualifying a variable or function as static in C or C++ at file scope means "Ssh! Don't tell the linker!". Java does not support this mean of static, either.

In English, the same word can have multiple meanings, depending on context. Look up any commonly-used word in the dictionary and you will find multiple definitions of that word. Some words not only have multiple meanings, they have multiple parts of speech. "Counter", for example, can be a noun, a verb, an adjective, or an adverb, depending on context. Other words can have contradictory meanings, depending on context. "Apology" can mean "I'm so sorry!" or it can mean "I am not sorry at all!" A premier example of the latter is "A Mathematician's Apology" by G. H. Hardy. English is not at all unique in this regard; the same applies to any language humans use to communicate with one another. As humans, we are quite used to words having different meanings depending on context.

There's an inherent conflict between having too few keywords and too many in a computer language. Lisp, forth, and smalltalk are very beautiful languages with very few, if any, keywords. They have a few special characters, e.g., open and close parentheses in lisp. (Full disclosure: I've programmed in all three of those languages, and I loved it.) There's a problem here: Good luck reading the code you yourself wrote six months after the fact. Even better luck turning that code over to someone else. As a result, these languages also have a rather limited number of adherents. Other languages go over the top and reserve a huge number of words as "keywords." (Full disclosure: I've been forced to program in those languages as well, and I hated it.)

Too few or too many keywords in a computer language results in cognitive dissonance. Having the same keyword have different contexts in different does not, because as humans, we are quite used to that.


6

Java Tutorial says

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.

Basically "static" means that the entity marked with it is divorced from the instances of a class. Static method doesn't have an instance associated with it. Static field is shared between all instances (essentially exist in the Class, not in the instance).
static nested classes are divorced from the enclosing instance. You are right that it is a bit confusing because you can have an instance of a static nested class with non-static methods and fields inside of it.
Think of the word static as saying "I am declaring an entity, a field, a method or an inner class, which is going to have no relationship to the enclosing instance"


6

All the mentioned uses of static have some commonality as I see it - in all cases they mean that the class/field/method is less tied to the class instance than would be the case without static. Certainly the equivalence between static fields and static methods in particular should be clear: they are the way to declare singleton (per-classloader) fields and methods that work on those fields, in a similar way to global objects in other languages.

Perhaps then the use of static for nested classes isn't as obviously in the same spirit, but it does share the aspect that you don't need an instance of the containing class to use this construct.

So I don't see these as being particularly inconsistent.

One answer to the more general question of why keywords are re-used for apparently different purposes in a programming language is that often features are introduced as a language evolves - but it is difficult to add new keywords since often break existing programs that may have used that as an identifier. Java, for example, actually reserves the keyword const even though it is unused in the language, perhaps to allow for future expansion!

This reluctance to add new keywords often leads to overloading old ones.

Linked


Related

Latest