I have an OuterClass and an NestedClass. Like this.
public class OuterClass
{
public class NestedClass
{
}
}
Whenever I try to call the constructor of NestedClass in a static context (like as a static field or a static method), I get a compiler error.
Here is an example code.
public class OuterClass
{
public class NestedClass
{
public static final NestedClass someStaticField = new NestedClass();
public static NestedClass someStaticMethod()
{
return new NestedClass();
}
}
}
And here are the compiler errors that I get.
$ javac OuterClass.java
OuterClass.java:7: error: non-static variable this cannot be referenced from a static context
public static final NestedClass someStaticField = new NestedClass();
^
OuterClass.java:12: error: non-static variable this cannot be referenced from a static context
return new NestedClass();
^
2 errors
What do these errors mean, and what should I be writing instead to achieve the desired outcome of being able to call the constructor in a static context?
The problem is that the
NestedClassis notstatic- neither implicitly nor explicitly declared as such - so it is an inner class. From Java Language Specification 8.1.3. Inner Classes and Enclosing Instances:To create an instance of such inner class, an instance of the enclosing (outer class) is needed. If not in a static context,
thisis implicitly used when creating such an instance. In a static context, there is nothisand we must provide the instance of the enclosing class. This is accomplish by using a qualified class instance creation expression like:as described in JLS 15.9. Class Instance Creation Expressions:
More details can be found in JLS 15.9.2. Determining Enclosing Instances.
Applying that to the code of the question, we could do:
A second possibility would be to not make the nested class an inner class by declaring it as
staticand avoiding the need for an enclosing instance:Which solution to use should be based on the specific use case and data model, not just because the compiler accepts it!
Note:
staticmembers of inner classes are allowed since Java 16 (JEP 359), so we can have record classes, which arestatic, declared in inner classes.