I have a simple nested class A. (In C I would use a struct.) I want to provide a default object A.DEFAULT of class A without having to call the constructor each time. So my idea was this:
class MyApplication {
class A {
int x;
double y;
public static final A DEFAULT = new A(0, 0.0);
public A(int x, double y) {
this.x = x;
this.y = y;
}
}
…
Obviously, this does not work, because the constructor cannot be called before the class has been loaded.
How to handle this? How does e. g. java.awt.Color.RED handle this?
CodePudding user response:
This has nothing to do with constructor calls, you've just made a couple of simple mistakes.
You haven't specified a type for DEFAULT:
public static final A DEFAULT
You cannot instantiate an A without an instance of MyApplication, as A is an inner class:
new MyApplication().new A(0, 0.0);
However you probably didn't intend to make A an inner class, so I would mark it as static. Without any extra context, it seems as if A has no relation to MyApplication so shouldn't depend on it.
Note: In Java 15 and below, static declarations weren't even allowed in inner classes (as pointed out by @Johannes Kuhn).
CodePudding user response:
Apart from the obvious problem that you missed a type (A) on the definition of DEFAULT...
The problem isn't that "the class has [not] been loaded". The problem is that, in Java, every instance of an inner class implicitly has a reference to the instance of the outer class that created it. Since there is no instance of the outer class when initializing the static field, you get an error:
MyApplication.java:5: error: non-static variable this cannot be referenced from a static context
public static final A DEFAULT = new A(0, 0.0);
^
And in all but the most recent Java versions, even declaring a static field inside a non-static inner class is illegal, no matter what value you give it:
MyApplication.java:5: error: Illegal static declaration in inner class MyApplication.A
public static final A DEFAULT = new A(0, 0.0);
^
modifier 'static' is only allowed in constant variable declarations
The solution is to make the inner class not have a reference to the outer class, which you do by declaring A as static:
class MyApplication {
static class A {
^^^^^^
