I understand there is one single instance per predefined constant of an enum type. Is that even right? Now, suppose there is an instance variable called value
of the enum, and suppose ONE
is a predefined constant. If value
is modified for (the) instance of ONE
then this affects all variables referring to ONE
. But what happens to the value of value
when the garbage collector gets rid of all instances of the enum? Do they ever get thrown away even?
Example
Here is a simple example where there are two variables A
and B
, both referring to ONE
. The value of value
is negated before B
is used for the first time. If the garbage collector had gotten rid of the instance of ONE
before the line Number B = Number.ONE;
, then the value of value
would have been "reset" back to 1, I presume. Is this correct?
The enum:
public enum Number
{
ONE(1), TWO(2), THREE(3);
int value;
Number(int value) { this.value = value; }
void negate() { value = -value; }
@Override
public String toString() { return "value: " + value; }
}
The main method:
public static void main(String[] args)
{
Number A = Number.ONE;
A.negate();
Number B = Number.ONE;
System.out.println(A + " " + B);
}
Output:
value: -1 value: -1
So my question is, can the output ever be the following (if say A = null;
is added before B
is used)?
value: -1 value: 1
Enums are implicitly public static final
fields, so they are never garbage collected.
EDIT
As kindly pointed out in the comments by @RealSkeptic, things are a little bit more complex in a jvm instance with multiple class loaders. Then static field values may disapear when their classes are unloaded.
However, by default, there is only one class loader which is alive as long as the jvm instance is alive, so in your example application it can never happen that static fields are garbage collected.
For this enum:
public enum FooEnum {
CONST
}
This byte code is generated:
Compiled from "FooEnum.java"
public final class FooEnum extends java.lang.Enum<FooEnum> {
public static final FooEnum CONST;
static {};
Code:
0: new #1 // class FooEnum
3: dup
4: ldc #12 // String CONST
6: iconst_0
7: invokespecial #13 // Method "<init>":(Ljava/lang/String;I)V
10: putstatic #17 // Field CONST:LFooEnum;
13: iconst_1
14: anewarray #1 // class FooEnum
17: dup
18: iconst_0
19: getstatic #17 // Field CONST:LFooEnum;
22: aastore
23: putstatic #19 // Field ENUM$VALUES:[LFooEnum;
26: return
public static FooEnum[] values();
// elided
public static FooEnum valueOf(java.lang.String);
// elided
}
CONST is a final static variable whose lifetime is that of the class.
Enums will only be garbage collected if the class is garbage collected.
From The Java Language Specification, Java SE 8 Edition section 8.9. Enum Types:
An enum type has no instances other than those defined by its enum constants. It is a compile-time error to attempt to explicitly instantiate an enum type (§15.9.1).
In addition to the compile-time error, three further mechanisms ensure that no instances of an enum type exist beyond those defined by its enum constants:
The final clone method in Enum ensures that enum constants can never be cloned.
Reflective instantiation of enum types is prohibited.
Special treatment by the serialization mechanism ensures that duplicate instances are never created as a result of deserialization.
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