Why ConcurrentHashMap.Segment and ConcurrentHashMap.HashEntry classes are static?
Why it is designed in this way ?
Basically all inner classes which does not need to use the properties of their enclosing classes are supposed to be static. This comes from the general principle in java which says that every object should have access to the least possible other objects.
Each inner non-static class contains an invisible field this$ which references it's parent object (ConcurrentHashMap) which creates an overhead of 8 bytes per entity (Segment or HashEntry). This is how parent's class fields are accessed - inner class is in some sort a syntax sugar for objects which belong to a single container (e.g. parent).
This is why inner classes should be replaced with static inner classes when possible.
#Andrey , #Adam I agree the points you presented but the real answer I got from effective java book. Item#22 Favor static member classes over nonstatic.
A common use of private static member classes is to represent
components of the object represented by their enclosing class.For
example, consider a Map instance, which associates keys with values.
Many Map implementations have an internal Entry object for each
key-value pair in the map. While each entry is associated with a map,
the methods on an entry (getKey, getValue, and setValue) do not need
access to the map. Therefore, it would be wasteful to use a nonstatic
member class to represent entries: a private static member class is
best.
If you declare a member class that does not require access to an
enclosing instance, always put the static modifier in its declaration.If you omit this modifier, each instance will
have an extraneous reference to its enclosing instance
lot more good stuff I got from item#22 but above are the main points.
Inner static class has a one beautiful feature that they are lazy loaded as it is explained in Bill Pugh Singleton Implementation, when we implement singleton pattern.
Other features that the static inner class provides is that the outside instance variables are not accessible. From here, we can not access non static methods either. There is no need to make separate instance to initialize that static class, Directly using ClassName.InnerStaticClass.method(), the method can be called.
Related
We know that a non-static inner class can be accessed using the instance of the outer class, so a static method is less meaningful inside a non-static class. But from Java 16 static methods are allowed inside a non-static inner class.
Why did this restriction exist in the first place? Why is this allowed in the newer version?
public class OuterClass {
class InnerClass {
static void printMe() {
System.out.println("Inside inner class");
}
}
public static void main(String[] args) {
InnerClass.printMe();
}
}
You're asking for reasoning of a change in Java 16, so you should start by checking the Release Notes to see if it has anything to say. It does:
JEP 395: Records (JDK-8246771)
tools/javac
Records have been added to the Java language. Records are a new kind of class in the Java language. They act as transparent carriers for immutable data with less ceremony than normal classes.
Since nested classes were first introduced to Java, with the exception of static final fields initialized by constant expressions, nested class declarations that are inner have been prohibited from declaring static members. This restriction applies to non-static member classes, local classes, and anonymous classes.
JEP 384: Records (Second Preview) added support for local interfaces, enum classes, and record classes, all of which are static definitions. This was a well-received enhancement, permitting coding styles that reduce the scope of certain declarations to local contexts.
While JEP 384 allowed for static local classes and interfaces, it did not relax the restriction on static member classes and interfaces of inner classes. An inner class could declare a static interface inside one of its method bodies, but not as a class member.
As a natural next step, JEP 395 further relaxes nesting restrictions, and permits static classes, methods, fields, etc., to be declared within inner classes.
For further details, see JEP 395.
The specific reasoning is given in JEP 395
Static members of inner classes
It is currently specified to be a compile-time error if an inner class declares a member that is explicitly or implicitly static, unless the member is a constant variable. This means that, for example, an inner class cannot declare a record class member, since nested record classes are implicitly static.
We relax this restriction in order to allow an inner class to declare members that are either explicitly or implicitly static. In particular, this allows an inner class to declare a static member that is a record class.
In other words, it was necessary to remove the restriction on static members of inner classes for a particular case; i.e. to allow record classes to be declared in inner classes. But they decided to take the opportunity to remove the restriction in all cases.
This implies that the designers have concluded that the original restriction as a whole was neither necessary for technical reasons or desirable.
why did this restriction exist in the first place?
That is a more difficult question. The decision to make that restriction would have been made in 1996 or early 1997 when Java 1.1 was being designed. It is unlikely that anyone can still accurately remember the reasons behind original decision. So unless someone can find a contemporaneous written source, we will never know for sure.
(Brian Goetz commented above: "... at the time nested was added (Java 1.1), there were multiple possible interpretations of static within another class, so the question was deferred.". That certainly makes sense, but this could be (just) one person's recollection of something that happened ~25 years ago. If it was me, I wouldn't be confident in my memory from that far back. Unless I had contemporaneous minutes, notes, etc to refer to.)
There is some speculation about the rationale for the original restriction here:
Why does Java prohibit static fields in inner classes?
This question already has answers here:
In laymans terms, what does 'static' mean in Java? [duplicate]
(6 answers)
Closed 7 years ago.
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.
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).
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).
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.
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.
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"
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.
I was reading a code snippet:
Class MyDAO{
public static final MyDAO DAO = new MyDAO();
public void loadData(){
//Hibernate Code to do something
}
...
}
So I'm amazed, and questions I'm facing right now is:
as static keyword denotes that a "member variable, or method, can be accessed without requiring an instantiation of the class to which it belongs". In simple terms, it means that you can call a method, even if you've never created the object to which it belongs.
What is the use of declaring a data member as static and instantiating a class then? is it a design pattern or what? and Most Importantly what is use of that? Any how when you say Class.staticMember how is the class loaded into the memory of JVM?
It can be used to implement Singleton pattern.
Data member is to be declared when you want it to hold same value across all instances(shared between different object of the class)
Declaring static is not a design pattern, but it is a way to design your application.
Further to this if your member is only consumed by methods in class and it is not expected to be accessed directly you can make it private static.
This is a way of providing the DAO object to the rest of the application as a global object. It is crude and ugly and makes testing hard, because it's difficult to provide a mock implementation of the DAO.
Static members are initialized at the time that the class is loaded. Classes are loaded lazily when they are first referenced. Other classes in the application can access this DAO without having to initialize it.
Code like this is why Dependency Injection frameworks (Spring, Guice, Hivemind, etc.) were created. This code makes the application depend on a specific implementation instead of on an abstraction, using dependency injection reduces coupling and increases testability by having the application depend on an abstraction and having the DI container be in charge of selecting the implementation and enforcing singleton scope.
What is the use of declaring a data member as static and instantiating a class then?
Having a data member being static does not give you any reason for not instantiating that class, because your class may still contain other non-static members.
So when do you not have to instantiate the class?
When all your members are static such as a utility class. An example is the Math class in Java.
Most Importantly what is use of that?
If you class contains non-static members, how do you expect those data to be accessed if you do not instantiate the class? Remember that your non-static members will not exist in memory if the class they belongs to is not instantiated.
is it a design pattern or what?
It has no direct relation with design patterns. Generally, you declare a member as static when it is a behaviour or property of the class itself and not individual objects.
Any how when you say Class.staticMember class is loaded into the memory of JVM.
I won't know exactly how Java memory works internally, but static members exist even before object instantiation which means variables declared as static are already created and loaded during runtime.
That also implies static members actually belongs to the class (not individual instance).
I'm writing an explanation for some code for a course, and have been accidentally using the words method and function interchangeably. I decided to go back over and fix the wording, but ran into a hole in my understanding.
From what I understand, a subroutine is a function if it doesn't act on an instance of a class (its effect is restricted to its explicit input/output), and is a method if it operates on an instance of a class (it may carry out side effects on the instance that make it impure).
There's a good discussion here on the topic. Note that by the accepted answer's definitions, a static method should actually be a function because an instance is never implicitly passed, and it doesn't have access to any instance's members.
With this is mind though, shouldn't static methods actually be functions?
By their definition they don't act on particular instances of a class; they're only "tied" to the class because of relation. I've seen a few good looking sites that refer to static subroutines as "methods" though (Oracle, Fredosaurus, ProgrammingSimplified), so either they're all overlooking the terminology, or I'm missing something (my guess is the latter).
I'd like to make sure I am using the correct wording.
Can anybody clear this up?
This quote from 8.4.3.2 may help:
A method that is declared static is called a class method.
A method that is not declared static is called an instance method [...].
Class methods: associated with a class.
Instance methods: associated with an instance.
Java just wants you to "think object-oriented". Also, static methods have access to a surrounding scope which may include state. In a way, the class is like an object itself.
The simple answer is that when Java decided to call everything a "method", they didn't care about the distinction between a function and a method in theoretical computer science.
Static methods are not exactly functions, the difference is subtle, but important.
A static method using only given input parameters is essentially a function.
But static methods may access static variables and other static functions (also using static variables) so static methods may have a state which is fundamentally different to a function which are by definition stateless.
(ADDENDUM: While programmers are often not so strict with using "function" as definition, a strict function in computer science can access only input parameters). So defining this case of accessing static fields it is not valid to say that static methods are always functions.
Another difference which justifies the usage of "static method" is that you can define in C derivates global functions and global variables which can be accessed everywhere. If you cannot access the class which contain static methods, the methods are inaccessible, too. So "static methods" are limited in their scope by design in contrast to global functions.
In Java, a user-defined class is actually an instance of a subclass of java.lang.Class.
In this sense, static methods are attached to an instance of a conceptual class: they are attached to an instance of a subclass of java.lang.Class.
With this in mind, the term "class method" (an alternate name for Java's static methods) begins to make sense. And the term "class method" can be found in many places: Objective C, Smalltalk, and the JLS -- to name just a few.
In computer science function clearly maps to a static method. But "method" of a class is a bit generic, like "member" (field member, method member). There are wordings like
Data members and method members have two separate name spaces: .x and .x() can coexist.
So the reason is, that as the philosoph Ludwig Wittgenstein said, Language is a tool with different contexts. "Method" is a nice moniker in the citation above to categorize a "member".
Your thinking is right and it makes sense. It's just not established terminology in the Java community. Let me explain some internals that can help understand why the terminology subsists.
Java is a class based object oriented language. A method is always member of a class or instance (This is a general statement valid for other programming languages too). We think of class and instance being both objects.
Instance method (dynamic)
You cannot invoke this method from a class directly, you have to create an instance. Each instance references that method. You can overwrite a method definition with the exact same method signature (when subclassing), i.e. the reference points to a different method (which has the same signature, but can have a different method body). The method is dynamic.
Class method (static)
You only can invoke this method from the class directly, i.e. you don't need to create an instance of that class. There is only one global definition of that method in the whole program. You cannot overwrite the exact same method signature when the method is declared static, because there is only one definition valid for the whole program. Note that the method is member of the class object itself, the instances have all the same unique (and fix) reference to that method.
Here is another take on the terminology, using Scala as a mnemonic:
In Scala you have objects, which are singleton instances of an implicitly defined class 1.
Per your definition, we can call these subroutines belonging to the object methods, as they operate on a single instance of the class.
Additionally the object will also define class A, and create all of the methods in object A as static methods on class A (for interfacing with Java) [2].
Therefore we can say that the static methods of Java class A access the same members as the Scala singleton instance, which per your definition then deserve to be called (static) methods of class A.
Of course, the main difference is - method can use static fields, not only method parameters.
But there is additional one - polymorphism!
Results of evaluation Class A.doTheSameStaticMethod() and ClassB.doTheSameStaticMehod() will be depends of class. In this case function is impotent.
Each class has an object to represent it that is an instance of a subclass of the Class class. Static methods are really instance methods on these objects that are instances of a subclass of Class. They have access to state in the form of static fields, so they are not restricted to being just (stateless) functions. They are methods.
I know how to create a singleton object by declaring its constructor private. But my doubt is: can we create a singleton object by declaring all its methods and variables static. If so, what challenges we will face?
If you declare all methods and variables of a class static, you can still create arbitrary many instances of that class. These objects will have only the inherited methods and variables. But all newly declared methods and variable are global. That is very similar to a singleton object, but not the same.
E.g. let's say you have a singleton class implementing the Collection interface, than you can have only one instance. But you are free to give it to any method requiring a collection instance. That is impossible when you make everything in a class static.
Making members of classes static means you use the class not as class but as a namespace.
by declaring all variables and methods static, you are practiacally making it not an object. It will be similar to a c program with global variables more then a singleton pattern - very not OOP style!
You will also make it impossible for this class to implement any interface [remember there is no overriding with static methods...] again, not very OOP style.
When you do that, you can create as many instances of the class as you like, though the underlying things will remain unchanged.
Even if you don't create any instance, the attributes will remain: because static elements are properties of the class, not the object.
I guess that you're in the case where singleton is not needed because almost all your methods are static, that say that you don't have to retains any state in any object... like a singleton is designed for.
A singleton is a stateful object offering static methods, like would be a ConnectionPool's singleton for instance, that retains information about the underlying backend service.
So, I'd do is to decide whether you need some shared state to be kept in order to execute your methods. It will drive your implementation.