For an enumeration defined in a class, like
class OuterClass {
public enum Method {
GET,
PUT,
POST,
DELETE;
}
}
Is the enumeration a static nested class (https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html)? It seems to be the case judging from the syntax used to refer to it. Or is it a non-static nested class (an inner 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.
As per §8.9 of the JLS:
An enum declaration specifies a new enum type, a special kind of class type.
[...]
A nested enum type is implicitly static. It is permitted for the declaration of a nested enum type to redundantly specify the static modifier. [...]
The generated bytecode for the enum declaration is as follows:
// compiled from: OuterClass.java
public final static enum INNERCLASS ...
So yes, enum is a static nested class in this case - confirmation in the JLS.
Related
Java's inner classes can be static or non-static. Non-static inner classes are tied to an instance of the enclosing class.
Annotations are a type of Java interface, and like any other class, they can be defined inside a class. Similarly, they can be declared static or non-static. What is the difference between these two choices, is there any difference between how they're used by consuming code, and is there any scenario where it'd make sense to use one or the other?
Example:
public class AnnotationContainer {
public static #interface StaticAnnotation {}
public #interface NonstaticAnnotation {}
}
No difference at all. Nested interfaces are always static.
This is described in JLS Sec 8.5.1 (for classes):
A member interface is implicitly static (§9.1.1). It is permitted for the declaration of a member interface to redundantly specify the static modifier.
and JLS Sec 9.5 (for interfaces):
A member type declaration in an interface is implicitly public and static. It is permitted to redundantly specify either or both of these modifiers.
To expand a bit on Andy's correct answer that they are exactly the same because they are a special kind of interface declaration and "member interfaces" are implicitly static anyway:
JLS 10 9.6. Annotation Types:
An annotation type declaration specifies a new annotation type, a special kind of interface type. To distinguish an annotation type declaration from a normal interface declaration, the keyword interface is preceded by an at-sign (#).
JLS 10 8.5.1. Static Member Type Declarations :
A member interface is implicitly static (§9.1.1). It is permitted for the declaration of a member interface to redundantly specify the static modifier.
and JLS 10 9.1.1. Interface Modifiers
The modifier static pertains only to member interfaces (§8.5.1, §9.5), not to top level interfaces (§7.6).
Side note: interestingly, these Chapters do not use the term "nested interface" defined at the top of Chapter 9, but it seems to be a synonym for "member interface":
JLS 10 Chapter 9. Interfaces:
A nested interface is any interface whose declaration occurs within the body of another class or interface.
All variables inside of interface are public static and final.
So if I declare a nested class inside an interface will it also become static and final?
Interface I
{
class c
{
static void m(){ }
}
}
Lets find out. Lets create structure like:
interface Interface{
class Foo{}
}
Now we can test:
System.out.println("static: " + Modifier.isStatic(Interface.Foo.class.getModifiers()));
System.out.println("final: " + Modifier.isFinal(Interface.Foo.class.getModifiers()));
which prints:
static: true
final: false
So nested classes are implicitly static, but not final.
We can confirm it also by adding class Bar extends Foo{} to our interface. final classes can't be extended but since such code compiles fine it means Foo is not final.
Classes nested inside interfaces behave like static classes nested inside classes, in the sense that you do not need to have an instance of an outer class in order to construct an instance of a nested class. According to Java Language Specification, §8.1.3:
8.1.3 Inner Classes and Enclosing Instances
[...] A member class of an interface is implicitly static (§9.5) so is never considered to be an inner class.
However, these classes are not final, unless you explicitly designate them as such. This makes sense, because classes that implement an interface may need an opportunity to extend nested classes defined inside the interface.
The following won't compile:
class Outer<T> {
class Inner {
}
static class Nested {
Inner inner; // Error: Outer.this cannot be referenced from a static context
}
}
However, if I remove <T>, it compiles. Why the inconsistency?
Also, if I say Outer.Inner inner;, instead of Inner inner;, it compiles. Again, why the inconsistency?
I'd expect an error in either all cases or none. Could anyone explain what's going on?
Why the inconsistency?
I would say this is not inconsistency at all. This is basically a problem of understanding of generics. Consider the following code (Your modified code):
class Outer<T> {
class Inner{
T t;//Added this extra line
}
static class Nested {
Inner inner;
}
}
In this above example is somewhat similar to what you have written only I have added a new variable t of type T which is the generics of Outer class in the class Inner. Now in this above example would not compile because there is a non-static or runtime reference present in the Inner class, so, when you declare Inner in a static class Nested the JAVA complier does not know the type of T, which is only declared in the runtime, so you get an error. But in your case you have done nothing like that but still the compiler does not know whether something like that is present or not. So it gives the error.
Now in the second case you have removed the generic T from the class declaration of the Outer. So there is no possibility of declaring variable t in the Inner class so there is no error.
In the third case you declared Outer.Inner for the type of variable inner and it compiled successfully. Here the compiler considered Outer as RAW TYPE. But this type of raw type declarations should be avoided. So it would be better to write:
Outer<?>.Inner inner;
Here Java compiler considers Outer to take any object as parameters which would inherit Object.
class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.
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.
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();
For more information see the below click:
https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
In Java a nested class is an inner class that is declared static. E.g.:
class Basic{
public static class NestedClass{};
}
I am wondering if a nested class is a singleton by default, or if I may create a list of instances such as
class Basic{
public static NestedClass{};
List<NestedClass> items;
}
No, it's not a singleton (where did you get that idea?). Apart from the fact that it's a static nested class (and that does not imply that it's a singleton), it's a normal class as any other - in particular, you can create as many different instances of NestedClass as you want. If you need it to be a singleton, then you'll have to explicitly code it yourself.
In Java a nested class is an inner class that is declared static.
No. In Java an inner class is a nested class that is not explicitly or implicitly declared static. JLS #8.1.3. You have this back to front.
I am wondering if a nested class is a singleton by default
No.
Nesting, static, and inner have nothing to do with singletons.
I have a confusion here.
If I cannot declare a class as static, how does enum works?
It looks like a static class, because it gets instantiated itself and can be called anywhere.
Looks like I can use enum almost like other static fields.
Is it safe to use enum?
enum types are automatically static. You can't have a non-static enum, so the static is implied.
JLS 8.9:
Nested enum types are implicitly static. It is permissible to explicitly declare a nested enum type to be static.
Each enum which you are declaring inside an enum type is static member of your enum type.And the type of your enum variables is the type of your enum,in short they are self typed.