0

I use the following code and got an error while calculation a value inside enum:

enum elPosition {
    p1(
            (boxX*0 + boxX/2),
            (boxY*0 + boxY/2)
    ),
    p2(
            (boxX*1 + boxX/2),
            (boxY*1 + boxY/2)
    ),
    p3(
            (boxX*2 + boxX/2),
            (boxY*2 + boxY/2)
    );

    private double xPosition;
    private double yPosition;

    elPosition(final double xPosition, final double yPosition) {
        this.xPosition = xPosition;
        this.yPosition = yPosition;
    }

    private static final double boxX = 10;
    private static final double boxY = 10;

    public double getXPosition() {
    return xPosition;
    }

    public double getYPosition() {
        return yPosition;
    }
}

If instead of calculation some value is used, no error occurs.

Sae1962
  • 1,122
  • 15
  • 31
Artur
  • 661
  • 1
  • 6
  • 23
  • 1
    what is the error? – jhamon Sep 04 '19 at 09:27
  • illegal forward reference – Artur Sep 04 '19 at 09:30
  • You need to make `get..Position` methods abstract, and implement them for each enum constant. Probably. Also, please note that Java naming conventions states that class/interface/enum names are CamelCase and start with capital letter. – M. Prokhorov Sep 04 '19 at 09:36
  • @FedericoklezCulloca Nah. That's for constructor content, not for constructor calls. The problem is different. – kumesana Sep 04 '19 at 09:42
  • @EamonScullion Nah, not related at all – kumesana Sep 04 '19 at 09:43
  • @kumesana, just put the two constants in a different class and you will see that the issues disappears. And I would add that based on the JDK, the error message state that the variable can't be used before it is defined. If the constants are not ready in the constructor, it will not be ready the statement before that, when we call the constructor... – AxelH Sep 04 '19 at 09:49
  • @AxelH I know that. Hell, you can even access the variables through a class qualifier of the current class and the problem disappears too. The problem is that it is failry unsatisfying syntax. With the variables in another class, you can import static them, but you need an artificial other class. I'm thinking up satisfying solutions. – kumesana Sep 04 '19 at 09:51

2 Answers2

1

I'd say "Illegal forward reference" is a clear enough error message with what's getting in the way.

To try and prevent abusively hacky code, Java just flat-out won't let you access variables before they're declared.

It so happens though, that as these variables are constants, their values are evaluated at compile time and the order of their declaration doesn't actually matter. Java is just not bending its general rules to allow you to do that in this specific case.

One way I'd solve it, is by calling private static methods to get the values:

enum ElPosition {
  P1(
          (boxX() *0 + boxX() /2),
          (boxY() *0 + boxY() /2)
  ),
  P2(
          (boxX() *1 + boxX() /2),
          (boxY() *1 + boxY() /2)
  ),
  P3(
          (boxX() *2 + boxX() /2),
          (boxY() *2 + boxY() /2)
  );

  private double xPosition;
  private double yPosition;

  ElPosition(final double xPosition, final double yPosition) {
    this.xPosition = xPosition;
    this.yPosition = yPosition;
  }

  private static final double BOX_X = 10;
  private static final double BOX_Y = 10;

  private static double boxX() {
    return BOX_X;
  }

  private static double boxY() {
    return BOX_Y;
  }

  public double getXPosition() {
    return xPosition;
  }

  public double getYPosition() {
    return yPosition;
  }
}
kumesana
  • 2,495
  • 1
  • 9
  • 10
  • Now try with `private static final Double BOX_X = Double.valueOf(10)`. You will see that this solution only works with primitive type. – AxelH Sep 04 '19 at 12:33
  • I'm aware of that. It sounds to me like the whole point of the question was to leverage that these variables are constants, which Double wrappers aren't. If you don't have constants to play with, renounce that construct. – kumesana Sep 04 '19 at 13:15
  • `Double` and every other primitive wrapper are immutable... so I don't see any problem to use them from a constant. – AxelH Sep 04 '19 at 14:11
  • @AxelH I meant a compile-time constant, that thing Java does with the variables it knows the values of at compile time, and therefore it substitutes the variables with their values. It's a real thing and wanting to leverage it is sort of understandable. Alternatives would force to create a different class, which kinds of suck. – kumesana Sep 04 '19 at 14:21
0

The problem is that boxX & boxYaren't declared at the moment when you try to use them. Statics are known in line order and you cannot declare a static before the enum constants.

Erik
  • 2,013
  • 11
  • 17