For a class being static, it is required it to be not a top level class. Since all classes belong to Object class which is the superior of all classes, then why can't we create a class with static keyword? Why is static classes allowed only in nested scenario.
All the classes in Java (transitively) extend Object, they are not inner classes inside it.
static wouldn't mean anything for top level classes, and therefore is forbidden. For inner classes, static means the same thing it means for other members (such as data members and methods) - the inner class belongs to the outer class, not to a specific instance of it.
This question already has answers here:
What is the point of "final class" in Java?
(24 answers)
Closed 9 years ago.
In Java (and in Android), what's the use of static class and final class declarations?
My question is not about static instances but class declarations like,
static class StaticClass {
//variables and methods
}
and
final class FinalClass {
//variables and methods
}
Thanks,
Static Nested Classes
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.
Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
Static nested classes are accessed using the enclosing class name:
OuterClass.StaticNestedClass
For example, to create an object for the static nested class, use this syntax:
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Final Classes
A class that is declared final cannot be subclassed. This is particularly useful, for example, when creating an immutable class like the String class.
http://docs.oracle.com/javase/tutorial/java/IandI/final.html
final classes will restrict for further extends (Inherit).
You can not use static keyword on outer class,static is permitted only to inner classes Static classes
You make a class final so it can not be extended. Usually it makes sense if you'are creating a library (or working on a part of a big project), so your clients are not able to extend the class and modify the existing behavior. In your own program there's little reason to make a class final unless it's a big program and you can inadvertently forget things.
Static inner classes are for things that logically belongs to an outer (containing) class but which have no dependencies on the state of the outer class. For example you can have a Parser class and an inner Parser.Listener class. Normally if you decide to have an inner class try, first, to make it static, if possible, to simplify things.
You could do without both final and static inner classes then with experience you will find use for them.
other class can not extends the final class exmple String is final class so you cannot extends this class.
You cannot have a 'top-level' class declared static. You can only have an inner class with the modifier 'static'.
static inner class only access the static member of the outer class
if you make a class as final then it can not be inherited. Generally top level class can not be made static however inner class can be made as static and Nested static class doesn’t need reference of Outer class
static and final class in java
you can't mark a class static ?
yes, if it is nested class
no, if it is normal class.
if you mark a nested class static it will work as fully flagged class just use a classname.staticClassNmae to access it.
if you mark a class final , it can't be inherited , a good example of this String class in java.
Is there a difference between initialisation of a static nested class and top level class?I understand that static class doesnt require an enclosing class instance but what happens if there are multiple instances of the static nested class? Just like static variables are shared by class instances, will the instances of the static class be shared also?
Let me see if I understand your question correctly.
A class can declare nested classes.
If a class C1 declares a non-static inner class C2, then C2 has access to all of C1's fields and methods, regardless of their access modifiers.
C2 is, in fact, treated as a field: its declaration is loaded whenever a new instance of C1 is created. This means that non-static inner classes are rather more expensive than static ones, and should be avoided if not strictly necessary.
If a class C1 declares a static inner class C3, then C3 is shared across all instances of C1. It has access to all static methods and fields of C1, but not to non static ones - C3 is by definition not tied to a specific instance of C1, so there is nothing for it to have access to.
When you declare a static inner class, you're not saying anything about its instances. You're just telling the compiler that the class' definition is shared across all instances of the enclosing class. So, no, instances of the nested static class aren't shared automatically.
A static nested class does not required an instance of the enclosing class (as you point out) so there is nothing to share.
If you have a static variable then every instance of the class will hold a reference to the same static variable. Changes in one class will change the variable in all classes.
As a class is immutable at run time then this same logic doesn't carry through.
An instance of a static nested class is effectively the same as an instance of any other class.
The only way an instance would be shared would be if you had a static variable pointing to an instance of a static nested class. In this case it is the same as any other static variable.
As is pointed out the the tutorial the only real different between a static nested class and a top level class is that a static nested class can access private static members of it's enclosing class.
Every class is a singleton object of type Class.
A static inner class is the base case. It is the other, normal inner class, that also has an OuterClass.this pointer for its instance objects.
So as such, there is no difference in class initialisation of any class.
The nested class as you declared it as "static class" does not differ from another top level class like inner class does. Adding the static to it declaration you promote it to be separated from owner class that became only a namespace for it.
package org.stack.question
public class Top {
public static class Nested {
}
}
To create a instance of Nested class you must only do this
Object instance = new org.stack.question.Top.Nested();
From specification:
Nested classes that are not inner classes may declare static members
freely, in accordance with the usual rules of the Java programming
language. Member interfaces (§8.5) are implicitly static so they are
never considered to be inner classes.
If I nest a class inside another, does the nested class automatically become a subclass of the parent class? Would the nested class have access to all the public methods, vairables of the parent class?
Oh sorry - the programming language i am referring mainly to is Java!
If I nest a class inside another, does the nested class automatically become a subclass of the parent class?
No
Would the nested class have access to all the public methods, vairables of the parent class?
If the inner class is not static, yes. It also has access to any other members, static or not, and public or not. If the nested class is declared static then there is no enclosing instance, so it would only have access to the static members of the outer ("parent") class.
Nested class is not subclass of parent class. If nested class is not static , it can access all methods and variables of the parent class. If nested class is static, then it can access only static fields and methods.
What language is this in reference to? For most languages, an inner class and a subclass are completely different things. An inner class is a "member" of the outer class, just as fields and methods are members of the outer class. And just like any (static) method of the outer class can access all (static) class members, usually inner classes have access, as members of the outer class, to all other members of the outer class. (This is definitely not true of all OO languages, however.)
Why can't we have static method in a non-static inner class?
public class Foo {
class Bar {
static void method() {} // Compiler error
}
}
If I make the inner class static it works. Why?
public class Foo {
static class Bar { // now static
static void method() {}
}
}
In Java 16+, both of these are valid.
Because an instance of an inner class is implicitly associated with an instance of its outer class, it cannot define any static methods itself. Since 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, it's safe to declare static methods in a static nested class.
There's not much point to allowing a static method in a non-static inner class; how would you access it? You cannot access (at least initially) a non-static inner class instance without going through an outer class instance. There is no purely static way to create a non-static inner class.
For an outer class Outer, you can access a static method test() like this:
Outer.test();
For a static inner class Inner, you can access its static method innerTest() like this:
Outer.Inner.innerTest();
However, if Inner is not static, there is now no purely static way to reference the method innertest. Non-static inner classes are tied to a specific instance of their outer class. A function is different from a constant, in that a reference to Outer.Inner.CONSTANT is guaranteed to be unambiguous in a way that a function call Outer.Inner.staticFunction(); is not. Let's say you have Inner.staticFunction() that calls getState(), which is defined in Outer. If you try to invoke that static function, you now have an ambiguous reference to the Inner class. That is, on which instance of the inner class do you invoke the static function? It matters. See, there is no truly static way to reference that static method, due to the implicit reference to the outer object.
Paul Bellora is correct that the language designers could have allowed this. They would then have to carefully disallow any access to the implicit reference to the outer class in static methods of the non-static inner class. At this point, what is the value to this being an inner class if you cannot reference the outer class, except statically? And if static access is fine, then why not declare the whole inner class static? If you simply make the inner class itself static, then you have no implicit reference to the outer class, and you no longer have this ambiguity.
If you actually need static methods on a non-static inner class, then you probably need to rethink your design.
I have a theory, which may or may not be correct.
First, you should know some things about how inner classes are implemented in Java. Suppose you've got this class:
class Outer {
private int foo = 0;
class Inner implements Runnable {
public void run(){ foo++; }
}
public Runnable newFooIncrementer(){ return new Inner(); }
}
When you compile it, the generated bytecode will look as if you wrote something like this:
class Outer {
private int foo = 0;
static class Inner implements Runnable {
private final Outer this$0;
public Inner(Outer outer){
this$0 = outer;
}
public void run(){ this$0.foo++; }
}
public Runnable newFooIncrementer(){ return new Inner(this); }
}
Now, if we did allow static methods in non-static inner classes, you might want to do something like this.
class Outer {
private int foo = 0;
class Inner {
public static void incrFoo(){ foo++; }
}
}
... which looks fairly reasonable, as the Inner class seems to have one incarnation per Outer instance. But as we saw above, the non-static inner classes really are just syntactic sugar for static "inner" classes, so the last example would be approximately equivalent to:
class Outer {
private int foo = 0;
static class Inner {
private final Outer this$0;
public Inner(Outer outer){
this$0 = outer;
}
public static void incrFoo(){ this$0.foo++; }
}
}
... which clearly won't work, since this$0 is non-static. This sort of explains why static methods aren't allowed (although you could make the argument that you could allow static methods as long as they didn't reference the enclosing object), and why you can't have non-final static fields (it would be counter-intuitive if instances of non-static inner classes from different objects shared "static state"). It also explains why final fields are allowed (as long as they don't reference the enclosing object).
The only reason is "not a must", so why bother to support it?
Syntactically,there is no reason to prohibit an inner class from having static members. Although an instance of Inner is associated with an instance of Outer, it's still possible to use Outer.Inner.myStatic to refer a static member of Inner if java decides to do so.
If you need to share something among all the instances of Inner, you can just put them into Outer as static members. This is not worse than you use static members in Inner, where Outer can still access any private member of Inner anyway(does not improve encapsulation).
If you need to share something among all the instances of Inner created by one outer object,it makes more sense to put them into Outer class as ordinary members.
I don't agree the opinion that "a static nested class is pretty much just a top level class". I think its better to really regard a static nested class/inner class as a part of the outer class, because they can access outer class's private members. And members of outer class are "members of inner class" as well. So there is no need to support static member in inner class. An ordinary/static member in outer class will suffice.
From: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.
Oracle's explanation is superficial and handwavy. Since there's no technical or syntactic reason to preempt static members within an inner class (it's allowed in other languages such as C#) the Java designers' motivation was likely conceptual taste and/or a matter of technical convenience.
Here's my speculation:
Unlike top-level classes, inner classes are instance-dependent: an inner-class instance is associated with an instance of every one of its outer classes and has direct access to their members. This is the chief motivation for having them in Java. Expressed another way: an inner class is meant for instantiation in the context of an outer class instance. Without an outer class instance, an inner class ought not be any more usable than the other instance members of the outer class. Let's refer to this as the instance-dependent spirit of inner classes.
The very nature of static members (which are NOT object-oriented) clashes with the instance-dependent spirit of inner classes (which IS object-oriented) because you can reference/call a static member of an inner class without an outer class instance by using the qualified inner class name.
Static variables in particular may offend in yet another way: two instances of an inner class that are associated with different instances of the outer class would share static variables. Since variables are a component of state, the two inner class instances would, in effect, share state independently of the outer class instances they're associated with. It’s not that it’s unacceptable that static variables work this way (we accept them in Java as a sensible compromise to OOP purity), but there’s arguably a deeper offense to be had by allowing them in inner classes whose instances are already coupled with outer class instances by design. Forbidding static members within inner classes in favor of the instance-dependent spirit reaps the added bonus of preempting this deeper OOP offense.
On the other hand, no such offense is entailed by static constants, which do not meaningfully constitute state and so these are allowable. Why not forbid static constants for maximum consistency with the instance-dependent spirit? Perhaps because constants need not take up more memory than necessary (if they're forced to be non-static then they’re copied into every inner class instance which is potentially wasteful). Otherwise I can’t imagine the reason for the exception.
It may not be rock-solid reasoning but IMO it makes the most sense of Oracle's cursory remark on the matter.
Short answer: The mental model most programmers have of how scope works is not the model used by javac. Matching the more intuitive model would have required a big change to how javac works.
The main reason that static members in inner classes are desirable is for code cleanliness - a static member used only by an inner class ought to live inside it, rather than having to be placed in the outer class. Consider:
class Outer {
int outID;
class Inner {
static int nextID;
int id = nextID++;
String getID() {
return outID + ":" + id;
}
}
}
Consider what is going on in getID() when I use the unqualified identifier "outID". The scope in which this identifier appears looks something like:
Outer -> Inner -> getID()
Here, again because this is just how javac works, the "Outer" level of the scope includes both static and instance members of Outer. This is confusing because we are usually told to think of the static part of a class as another level of the scope:
Outer static -> Outer instance -> instanceMethod()
\----> staticMethod()
In this way of thinking about it, of course staticMethod() can only see static members of Outer. But if that were how javac works, then referencing an instance variable in a static method would result in a "name cannot be resolved" error. What really happens is that the name is found in scope, but then an extra level of check kicks in and figures out that the name was declared in an instance context and is being referenced from a static context.
OK, how does this relate to inner classes? Naively, we think there is no reason inner classes can't have a static scope, because we are picturing the scope working like this:
Outer static -> Outer instance -> Inner instance -> getID()
\------ Inner static ------^
In other words, static declarations in the inner class and instance declarations in the outer class are both in scope within the instance context of the inner class, but neither of these is actually nested in the other; both are instead nested in the static scope of Outer.
That's just not how javac works - there is a single level of scope for both static and instance members, and scope always strictly nests. Even inheritance is implemented by copying declarations into the subclass rather than branching and searching the superclass scope.
To support static members of inner classes javac would have to either split static and instance scopes and support branching and rejoining scope hierarchies, or it would have to extend its simple boolean "static context" idea to change to track the type of context at all levels of nested class in the current scope.
Why can't we have static method in a non-static inner class ?
Note: A non-static nested class is known as inner class so you do not have non-static inner class as such.
An inner class instance has no existence without a corresponding instance of outer class. An inner class cannot declare static members other than compile time constants. If it were allowed then there would have been ambiguity about meaning of static. In that case there would have been certain confusions:
Does it mean there is only one instance in VM?
Or only one instance per outer object?
That is why the designers probably took the decision of not handling this issue at all.
If I make the inner class static it works. Why ?
Again you cannot make an inner class static rather you can declare a static class as nested. In that case this nested class is actually part of outer class and can have static members without any issue.
This topic has garnered attention from many, still I will try to explain in the most simplest of terms.
Firstly, with reference to http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1, a class or interface is initialized immediately before the first occurence/invocation of any member which is preceeded by the static keyword.
So, if we put up with a static member within an inner class, it will lead to the initialization of the inner class, not necessarily the outer/enclosing class. So, we hamper the class initialization sequence.
Also consider the fact that a non-static inner class is associated with the instance of an enclosing/outer class. So, associating with an instance will mean, that the inner class will exist inside an Outer class instance and will be different amongst instances.
Simplifying the point, in order to access the static member we need an instance of an Outer class, from which we will again need to create an instance of non-static inner class. Static members are not supposed to be bound to instances and therefore you receive a compilation error.
The work to add records to JDK16 also mentions that static methods and fields can now be used with inner classes, even permitting main() to launch the class.
For example this compiles and runs in JDK16, and can select either main() to be run as java Outer or java Outer$Inner:
public class Outer {
public static void main(String[] args) {
System.out.println("Outer class main xxx="+Inner.xxx+" nnn="+(++Inner.nnn)+" iii="+(--iii));
aaa();
Inner.zzz();
}
public static void aaa() {
System.out.println("aaa() nnn="+(++Inner.nnn)+" iii="+(--iii));
}
public static int iii = 100;
class Inner {
public static final String xxx= "yyy";
public static int nnn = 0;
public static void zzz() {
System.out.println("zzz() "+" nnn="+(++nnn)+" iii="+(--iii));
}
public static void main(String[] args) {
System.out.println("Inner class main xxx="+xxx+" nnn="+(++nnn)+" iii="+(--iii));
zzz();
aaa();
}
}
}
An inner class is something completely different from a static nested class although both are similar in syntax. Static nested classes are only a means for grouping whereas inner classes have a strong association - and access to all values of - their outer class. You should be sure why you want to use an inner class and then it should come pretty natural which one you have to use. If you need to declare a static method it's probably a static nested class you want anyway.
First of all why someone want to define the static member in a non-static inner class? answer is, so that the outer class member can use those static member with the inner class name only, Right?
But for this case we can directly define the member in outer class. which will be associated with all object of inner class, within the outer class instance.
like below code,
public class Outer {
class Inner {
public static void method() {
}
}
}
can be written like this
public class Outer {
void method() {
}
class Inner {
}
}
So in my opinion not to complicate the code java designer is not allowing this functionality or we may see this functionality in future releases with some more features.
suppose there are two instances of outer class & they both have instantiated inner class.Now if inner class has one static member then it will keep only one copy of that member in heap area.In this case both objects of outer class will refer to this single copy & they can alter it together.This can cause "Dirty read" situation hence to prevent this Java has applied this restriction.Another strong point to support this argument is that java allows final static members here, those whose values can't be changed from either of outer class object.
Please do let me if i am wrong.
Try to treat the class as a normal field, then you will understand.
//something must be static. Suppose something is an inner class, then it has static keyword which means it's a static class
Outer.something
You are allowed static methods on static nested classes. For example
public class Outer {
public static class Inner {
public static void method() {
}
}
}
It is useless to have inner class members as static because you won't be able to access them in the first place.
Think about this, to access a static member you use className.memberName ,, in our case , it should be something like outerclassName.innerclassName.memberName,,, now do you see why innerclass must be static....