In Java, are enum types inside a class static?
Yes, nested enums are implicitly static.
From the language specification section 8.9:
Nested enum types are implicitly
static. It is permissable to
explicitly declare a nested enum type
to be static.
Enums defined in a class is a static nested class?
The JLS says
An enum declaration specifies a new enum type, a special kind of class type.
So it looks like the word from Oracle is that enums are classes.
If you declare an enum inside another class, then yes, it's an inner class. And enums are always static, so yes, it's fair to call an enum a static inner class (or nested class) when it's declared in another class.
Are inner classes in enums always static in Java?
static
keyword is not redundant. You may create a static nested class (with the static
keyword) or an inner class (without it). In the first case the class won't be assigned to any particular enum value. In the second case, instances of the inner class need to have an enclosing instance - one of the enum
values:
public class Test {
public static void main(String[] args) {
MyEnum.VALUE_1.createInnerObject().showName();
MyEnum.VALUE_2.createInnerObject().showName();
}
public enum MyEnum {
VALUE_1, VALUE_2;
public MyInnerClass createInnerObject() {
return new MyInnerClass();
}
private class MyInnerClass {
public void showName() {
System.out.println("Inner class assigned to " + MyEnum.this + " instance");
}
}
}
}
In the example above you can't create an instance of the MyInnerClass
directly from the MyEnum
:
new MyEnum.MyInnerClass(); // this will fail
In order to do this, you need to have a static
nested class, but then you can't use something like MyEnum.this
.
Are java enum variables static?
Yes, instances are implicitly static
and final
. This means that the code is unwise. Imagine two threads both calling SINGLE.setOperation(Type)
; you will have no confidence in what you are calling.
From the Java Language Specification, Section 8.9:
Enum types (§8.9) must not be declared abstract; doing so will result in a compile-time error.
An enum type is implicitly final unless it contains at least one enum constant that has a class body.
It is a compile-time error to explicitly declare an enum type to be final.
Nested enum types are implicitly static. It is permissible to explicitly declare a nested enum type to be static.
And in the next section:
The body of an enum type may contain enum constants. An enum constant defines an instance of the enum type.
Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.
Static enum vs. Non-static enum
All enum
s are effectively static
. If you have a nested enum, it is much the same as a static class
.
All classes are lazily loaded (enums or otherwise) however when they are loaded they are loaded all at once. i.e. you can't have a few constants loaded but not others (except in the middle of class initialization)
Java allows certain modifiers to be implicit to avoid having to declare them all the time. This means that adding a modifier doesn't necessarily do anything other than provide a longer way of writing the same thing.
Default modifiers for
class field/method/nested class - package local, non-final, non-static
enum and nested enum - package local, final and static
interface field - public static final
interface method - public abstract
nested class in an interface - public static
, non-final
Note: while static
is optional for an enum
it is always static. However, final
cannot be set for an enum even though it is always notionally final
(Technically you can have subclasses with overridden implementations for constants)
EDIT: The only place you need to use static
with enum
is with import static
of an enum's value. Thank you @man910
Are enum types declared in a class implicitly static?
Yes, it is. The language specification even says so. From the JLS section 8.9 (enums):
Nested enum types are implicitly static. It is permissable to explicitly declare a nested enum type to be static.
Private enums and static fields in the enclosing class
This is a bit all over the place in the JLS. The When Initialization Occurs chapter states
The intent is that a class or interface type has a set of initializers
that put it in a consistent state, and that this state is the first
state that is observed by other classes. Thestatic
initializers and
class variable initializers are executed in textual order, and may not
refer to class variables declared in the class whose declarations
appear textually after the use, even though these class variables are
in scope (§8.3.3). This restriction is designed to detect, at compile
time, most circular or otherwise malformed initializations.
That bold snippet refers to the class directly containing the access.
enum
types are defined in the Java Language Specification, here
An enum declaration specifies a new enum type, a special kind of class type.
The fields you access in the Baz
constructor
Baz(String description) {
// Can access static fields from before the enum
first.add(description);
// Can access static fields from _after_ the enum
second.add(description);
}
are not class variables declared in the class, the enum type Baz
. The access is therefore allowed.
We can go even deeper into the detailed class initialization procedure, which explains that each class (class, interface, enum) is initialized independently. However, we can create an example that sees yet-to-be-initialized values
public class Example {
public static void main(String[] args) throws Exception {
new Bar();
}
}
class Bar {
static Foo foo = Foo.A;
static Integer max = 42;
enum Foo {
A;
Foo() {
System.out.println(max);
}
}
}
This will print null
. The access to max
is allowed in the enum
type's constructor although our program execution reached the access before max
was initialized. The JLS warns against this
The fact that initialization code is unrestricted allows examples to
be constructed where the value of a class variable can be observed
when it still has its initial default value, before its initializing
expression is evaluated, but such examples are rare in practice. (Such
examples can be also constructed for instance variable initialization
(§12.5).) The full power of the Java programming language is available
in these initializers; programmers must exercise some care.
Your original Foo
example introduces an extra rule, defined in the chapter on Enum Body Declarations .
It is a compile-time error to reference a static field of an enum type
from constructors, instance initializers, or instance variable
initializer expressions of the enum type, unless the field is a
constant variable (§4.12.4).
That rule blocks your Foo
snippet from compiling.
enum
constants translate to public static final
fields. These appear textually first in the enum
type definition and are therefore initialized first. Their initialization involves the constructor. The rules exists to prevent the constructor from seeing uninitialized values of other class variables that will necessarily be initialized later.
Nested Java enum definition - does declaring as static make a difference?
No, it makes no difference. However the reason is not because it is a member declaration inside an interface, as Jon says. The real reason is according to language spec (8.9) that
Nested enum types are implicitly
static. It is permissable to
explicitly declare a nested enum type
to be static.
At the following example static does not make any difference either (even though we have no interface):
public class A {
enum E {A,B};
}
public class A {
static enum E {A,B};
}
Another example with a nested private enum (not implicitly public).
public class A {
private static enum E {A,B}
}
Nested enum is static?
Your declaration of method()
is in the wrong place. You declare it in the constant body. But it doesn't override anything. It belongs in the enum body, not the instance body.
The instance subtype is declared in the static initializer for the enum constant. Since the context is static it does not have access to the enum instance variables.
Your enum declaration is not static, it is top-level, and top-level classes cannot be static.
Constant bodies define an implicit nested anonymous subclass of the enum, and do not constitute nested enums as meant by the JLS. Each constant is of a different anonymous subtype of the enum you're declaring, which subtype is not static. However, the subtype is declared in a static context, so that's why the code can't reach the instance variable.
EDIT: Useful references from the JLS
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.1
"The optional class body of an enum constant implicitly defines an anonymous class declaration (§15.9.5) that extends the immediately enclosing enum type. The class body is governed by the usual rules of anonymous classes; in particular it cannot contain any constructors. Instance methods declared in these class bodies may be invoked outside the enclosing enum type only if they override accessible methods in the enclosing enum type (§8.4.8)."
https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.9.5
"An anonymous class declaration is automatically derived from a class instance creation expression by the Java compiler. An anonymous class is never abstract (§8.1.1.1). An anonymous class is always implicitly final (§8.1.1.2). An anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.1)."
Is the enum inside a class static?
This
enum Value: char
{
UP, RIGHT, DOWN, LEFT
};
this is a declaration of a type. It is not a data member of the enclosing class. The class has only this private data member.
Value value_;
of the enumeration data.
An enumerations declaration declares named enumerators. But they in turn are not data members of the enclosing class.
It is the same if you will declare a nested structure inside a class. For example
struct A
{
struct B
{
int x = 10;
};
B b;
};
Here is only one data member of the class A that is B b. The data member inside the structure declaration only provides the declaration of the structure B.
Related Topics
Encoding Url Query Parameters in Java
Listening for Input Without Focus in Java
How to Capitalize the First Letter of a String in Java
Different War Files, Shared Resources
Understand Arraylist Indexoutofboundsexception in Android
Sort Data to Recyclerview Based on Latest Date from Firebase
Issue When Using a Custom Font - "Native Typeface Cannot Be Made"
Alertdialog with Custom View: Resize to Wrap the View's Content
Wait Until Firebase Retrieves Data
How to Convert Image to Byte Array in Java
Regex Look-Behind Without Obvious Maximum Length in Java
Find First Element by Predicate
Selenium Webdriver - Getcssvalue() Method
Customised Listview Using Arrayadapter Class in Android
Dateformat Parse - Not Return Date in Utc
How to Delete a File on Google Drive Using Google Drive Android API
Ksoap2 Org.Xmlpull.V1.Xmlpullparserexception Expected Start_Tag Error