Dúvida sobre ordem de inicialização de instance variables vs consts

Sou super novato em Java e estou com uma dúvida simples.

Na classe principal de um programa, criei uma const no topo da classe:

private static final int BOX_WIDTH = 180;

E uma instance variable no final dessa classe:

private int programX = (getWidth() - BOX_WIDTH)/2;

Quando usei a variável no método main dessa classe, o comportamento não foi o que eu esperava. Então, tirei o assignment da instance variable, deixando apenas a declaração:

private int programX;

E joguei o assignment pra dentro do método. E aí funcionou.

Fiquei então em dúvida sobre a ordem em que as coisas aconteceram no programa. Declarei uma constante no topo da classe e uma instance variable no final da classe que usa essa constante. Aí no momento em que o método main é chamado, eu não deveria ter o valor consistente dessa instance variable?

Uma variável de instância é criada no momento em que crias a tua instância.
Se o teu método getWidth() devolve uma variável width que ainda não foi inicializada (default é 0 para valores números nativos em variáveis de instância), o valor que getWidth() vai devolver é 0 e programX fica com -90.

Mas se deres mais contexto/colocares mais código será mais fácil de explicar.

Obrigado pela resposta.

Este é o programa completo (já corrigido):

import acm.graphics.*;
import acm.program.*;
import java.util.*;

public class Hierarchy extends GraphicsProgram {

    private static final int BOX_WIDTH = 180;
    private static final int SPACE_BETWEEN_BOXES = 20;
    private static final int BOX_HEIGHT = 50;

    public void run() {

        programX = (getWidth() - BOX_WIDTH)/2;
        programY = (getHeight() - BOX_HEIGHT*3)/2;
        programBottomX = programX + BOX_WIDTH/2;
        programBottomY = programY + BOX_HEIGHT;
        lowerBoxesY = programY + BOX_HEIGHT*2;

        GRect programBox = new GRect(programX, programY, BOX_WIDTH, BOX_HEIGHT);
        add(programBox);

        int wholeFigureX = (BOX_WIDTH*3 + SPACE_BETWEEN_BOXES*2);

        int gpX = (getWidth() - wholeFigureX)/2;
        int cpX = gpX + BOX_WIDTH + SPACE_BETWEEN_BOXES;
        int dpX = gpX + BOX_WIDTH*2 + SPACE_BETWEEN_BOXES*2;

        GRect gp = new GRect(gpX, lowerBoxesY, BOX_WIDTH, BOX_HEIGHT);
        GRect cp = new GRect(cpX, lowerBoxesY, BOX_WIDTH, BOX_HEIGHT);
        GRect dp = new GRect(dpX, lowerBoxesY, BOX_WIDTH, BOX_HEIGHT);
        add(gp);
        add(cp);
        add(dp);

       GLine gpLine = makeGLine(gpX);
       GLine cpLine = makeGLine(cpX);
       GLine dpLine = makeGLine(dpX);
       add(gpLine);
       add(cpLine);
       add(dpLine);

    }

    private GLine makeGLine(int x) {
        GLine line = new GLine(programBottomX, programBottomY, (x + BOX_WIDTH/2), lowerBoxesY);
        return line;
    }

    private int programX;
    private int programY;
    private int programBottomX;
    private int programBottomY;
    private int lowerBoxesY;

}

Pelo que entendi, então, o método getWidth() deve retornar 0 por padrão enquanto o método run() não é chamado, certo?

Não.
Eu estava a supor que simplesmente terias uma variavel que não estavas a inicializar antes de usar.
Neste caso, e “seguindo” o código vejo que esse getWidth() é herdado de outra classe e o seu valor depende de outros factores.

class acm.program.Program:

(...)
public int getWidth() {
	return getCentralRegionSize().width;
}
(...)
private Dimension getCentralRegionSize() {
	if (centerPanel == null) return super.getSize();
	if (initFinished) return centerPanel.getSize();
	Dimension size = (programFrame == null) ? super.getSize() : programFrame.getSize();
	size.width -= westPanel.getPreferredSize().width;
	size.width -= eastPanel.getPreferredSize().width;
	size.height -= northPanel.getPreferredSize().height;
	size.height -= southPanel.getPreferredSize().height;
	return size;
}
(...)

Teria de seguir tudo isto para perceber exatamente de onde vem. Mas, ao usares diretamente na declaração de instancia, ainda deveria ter aquele centerPanel a null e o initFinished a false.

Resumidamente, estavas a tentar obter a altura de um componente que ainda não havia sido completamente criado.

Entendi.
Muito obrigado!

Caramba, não tem palavras em português para instance variable, const e assignment?