I was using a static nested class in java for a particular use-case. A minimal example of the same is shown below:
public class Foo {
static int fooInner = getInner(); // CASE 1
private static class StaticFoo {
int fooInner = getInner(); // CASE 2
public int useFooInner(){
System.out.println(fooInner);
//do something
}
}
}
The question is how is the memory allocation in Case 1 different from that in case 2? Or is it the same? What if I make the case 2 variable static too. Will the memory usage differ?
NOTE: Please do not mention that shadowing will take place. Although I have put both the variables there, but it's an "OR" case and that's why the "CASE"s.
PS: I feel that the memory usage should be the same. Since the nested class is static, it won't be created for every object and thus the instance variable fooInner
(Case 2) will also be created just once. Thus, the getInner() function would run just once. But it is just at an abstract level + gut feeling. A more descriptive answer would be appreciated!
A non-static nested class has full access to the members of the class within which it is nested. A static nested class does not have a reference to a nesting instance, so a static nested class cannot invoke non-static methods or access non-static fields of an instance of the class within which it is nested.
Instance variables are created when an object is created with the use of the keyword 'new' and destroyed when the object is destroyed. Static variables are created when the program starts and destroyed when the program stops.
1) First and most important difference between Inner class and nested static class is that Inner class require instance of outer class for initialization and they are always associated with instance of enclosing class. On the other hand nested static class is not associated with any instance of enclosing class.
Explanation: The non-static nested class can access all the members of the enclosing class. All the data members and member functions can be accessed from the nested class. Even if the members are private, they can be accessed.
However, Using the class name is the preferred approach. A static variable is a property of a class. An instance variable is a property of an instance. A static variable is created only once when the classloader loads the class. An instance variable is created everytime an instance is created.
It's a completely independent entity, whose methods and variables doesn't have any access to the instances of the outer class. The static nested classes are not coupled with the outer object, they are faster, and they don't take heap/stack memory, because its not necessary to create instance of such class.
The static inner class can access the static members of the outer class directly. But, to access the instance members of the outer class you need to instantiate the outer class. Nested static class doesn’t need a reference of Outer class but a nonstatic nested class or Inner class requires Outer class reference.
In the case of creating instance, the instance of non static inner class is created with the reference of object of outer class in which it is defined. This means it have inclosing instance. But the instance of static inner class is created with the reference of Outer class, not with the reference of object of outer class.
They are different.
From a memory allocation point of view, a static inner class is no different from a top level class. Your StaticFoo
will be compiled to a class (Foo$StaticFoo.class
) that is essentially independent from its parent class at runtime. At compile time, there are access checks for private members.
So, in case 1, you have a static field in a class. It will be allocated as a field on a Foo.class
object on the heap. There will only be one instance per ClassLoader that loads the Foo class, which generally means just one shared instance for the whole JVM.
In case 2, you have an instance field in the Foo$StaticFoo
class. On the heap, there will be space allocated (and a value assigned) for (and in) each instance of StaticFoo created. Each StaticFoo that gets created will access its own instance of that field, and since it's not final
, the value of each instance can be independently changed.
If you changed StaticFoo.fooInner
to be static
, then it would be exactly the same as case 1.
Note: The above is true only for Java 8 and later. For earlier JVMs, that amount of memory allocated in each case still matches the description above, but static variables, as well as being singletons per ClassLoader, are also stored in a different memory pool: PermGen Space rather than the main heap. See this answer for more details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With