Quite often I see people using inner enums, for example:
public class Person {
enum Gender {
MALE,
FEMALE,
OTHER
}
...
}
I am unsure how it works internally, so I am wondering whether there will be new instances of this enum class each time someone creates a new person, such as new Person()
?
Will the inner enum keep costing more memory or will there only be a single one?
Follow up: Just have a quick test on the accepted answer in code editor(Java 11):
public class Person {
String name;
int Age;
Address address = new Address();//Usual way we see
public class Address {
String city;
String Country;
int number;
}
}
public class test {
public static void main(String[] args) {
var a = new Person.Address();//complains "innerclass.Person' is not an enclosing class, make Address Static"
var p = new Person();
var a1 = p.new Address();//correct syntax to create inner clas object outside its outer class
}
}
TBH, never expect such weird syntax of creating an inner class object. But considering we usually just use it in the outer class like how iterator is used in different data structure, it still makes sense that I feel strange about this. Finally, inner class object are created based on the actual needs and dependency on the outer class, so there is no efficiency issue
Regarding discussion between @Zabuzard and @user207421, both make a good point. user207421 points out that class is considered inner only when they are non-static. Enum and Record by nature are static: Oracle doc. It is good to learn from the root. But I do appreciate how Zabuzard explains everything in a way we can easily understand from scratch.
CodePudding user response:
Explanation
Nested enums are essentially static nested classes. They do not belong to instances of the outer class.
Regardless of how many persons you create, you will always only have a single enum Gender
floating around, thats it.
Same goes for its values, there are only 3 values of this enum - regardless of how many persons you create.
Inner classes
However, even if you have an inner (non-static) class, such as
class A {
class B { ... }
...
}
You will only have a single class B
in memory (as you worded it). There is essentially always just a single class.
Now, when you create instances of B
, you will have to create them based on a previously created instance of A
, since instances of B
now belong to instances of A
and can only exist within their context.
Therefore, they also share non-static properties of that particular A
instance. You will often see that being used for Iterator
implementations of data-structures.
Static nested vs decoupled
If you have a static nested class, such as
class A {
static class B { ... }
}
you might ask what the only real difference to actually fully decoupling them, as in
class A { ... }
class B { ... }
would be that the nesting makes clear that they somehow belong to each other, topic-wise. An example would be the Entry
class in Map
.
Notes on efficiency
You should actually stop bothering about efficiency on those minor things. Instead, think about readability for readers.
Efficiency, in the way you have in mind, is rarely ever a factor. And if, usually only in a very small spot in the whole code base (which is usually identified using a profiler).
So basically, unless you have a really good reason to not, always strive for the most readable and understandable solution.