0

I'm building a GUI program in Java that uses the BorderLayout. And specifically, it uses only the CENTER, PAGE_END, and LINE_END areas. I have a class for each area, and often they need to share info. My main class and PAGE_END class start out like this:

public class JSudokuSolver extends JFrame {
    protected static Dimension      sBoardDim = new Dimension(500, 500); 
    protected static Dimension     lineEndDim = new Dimension(200, 500); 
    protected static Dimension     pageEndDim = new Dimension(650, 120); 
    ...

public class PAGE_END_objs {
    static Dimension      pageEndDim = JSudokuSolver.pageEndDim;
    ...

Sometimes this works fine; sometimes it doesn't. When it doesn't, I get a null pointer (in this example) when trying to use 'pageEndDim' in the PAGE_END_objs code. Then in Eclipse Neon debug mode, if I hover over 'JSudokuSolver.pageEndDim', I do see the Dimension data. But, if I hover over 'pageEndDim =', I see 'null'.

To me, that looks like the static assignment hasn't happened yet. Yes/no? If yes, when does it happen, and what triggers it? If no, do you have helpful info, I hope? TIA!

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
KeyLawson
  • 1
  • 4
  • 4
    The `static` initialiser runs at class load time - the class cannot be accessed before it has been run. These variables, however, are not `final` - are you assigning them to `null` somewhere? – Boris the Spider Apr 08 '17 at 18:09
  • 2
    I think a [mcve] is necessary here – OneCricketeer Apr 08 '17 at 18:16
  • *"When is a class static variable statement executed?"* See [Java order of Initialization and Instantiation](http://stackoverflow.com/q/23093470/5221149) – Andreas Apr 08 '17 at 18:19
  • Wow! Thank you for your lightning responses! No, I don't assign these variables to null. Yes, all classes are in the same package. I will try the 'final' technique, and definitely read the "Java order of I and I" info. – KeyLawson Apr 08 '17 at 19:20
  • The static initializer runs _after_ the class loads, not _at_ load time. As the word implies, an initializer runs at _initialization_ time, which can be long after load time. Initialization of `JSudokuSolver` should be triggered during initialization of `PAGE_END_objs` (a non-convention-compliant and weak name) by the reference to `JSudokuSolver.pageEndDim`, so I'm guessing `PAGE_END_objs` isn't being initialized. See the JLS §12.4.1. – Lew Bloch Apr 08 '17 at 23:50
  • Thank you again for your assistance and insight. First, adding the keyword 'final' did not help. The problem seems to have been trying to reference objects that have not yet been created. Waiting until they have been created and then calling: public static void PAGE_END_Solver_access() { notes = PAGE_END_objs.notes; avail = JSudokuSolver.avail; trcb = JSudokuSolver.trcb; } ... solved the access problem. – KeyLawson Apr 11 '17 at 04:44

2 Answers2

2

The static variables for a class will be completely initialized before any code using the class can access them*, in a conforming Java runtime environment.

If you're getting an NPE accessing pageEndDim, something somewhere is assigning null to pageEndDim after the class is loaded. You might consider making those variables final.


* It gets a bit complicated if initializers rely on one another or you have static initializer blocks doing the init, but that's not the case here.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • "It gets a bit complicated if initializers rely on one another or you have static initializer blocks doing the init, but that's not the case here." But, that is precisely the case here! – Lew Bloch Apr 08 '17 at 23:51
  • @LewBloch: No, there are no `static` initializer blocks in the quoted code, nor any inter-dependencies between the initializers on the declarations. – T.J. Crowder Apr 09 '17 at 00:19
  • There are static initializations; they don't need to be blocks. And there is, too, a dependency. `PAGE_END_objs.pageEndDim` depends on `JSudokuSolver.pageEndDim` in its static initialization. – Lew Bloch Apr 09 '17 at 00:40
  • @LewBloch: I meant "rely on one another" **within a class**, as I think was perfectly clear. `PAGE_END_objs` accessing `JSudokuSolver.pageEndDim` triggers init of `JSudokuSolver`. At which point, it will not be `null`. There is no inter-dependency. – T.J. Crowder Apr 09 '17 at 00:42
  • While there is no class-internal dependency between static initializers, the one between classes is still significant and could very well be the source of the phenomenon in question. It's relevant! Whatever you meant to say, the fact that one static variable depends on the other is a dependency, and that dependency could lead to the observed problem. Maybe you meant "within a class", but it isn't what you said, and it is potentially just this between-class dependency that is the root of the problem. So instead of playing "he-said, she-said", let's see if that is the case. Shall we? – Lew Bloch Apr 09 '17 at 02:10
  • @LewBloch: *"and could very well be the source of the phenomenon in question"* How, *specifically*? All I'm hearing here is innuendo, not information. If you have an answer that addresses the symptom other than the above, please post it. I'd be keen to see the inter-class `static` initializer inter-dependency causing one of them to sometimes be `null` you're suggesting. – T.J. Crowder Apr 09 '17 at 07:19
  • If the referring class was not initialized, the variable in question would be `null`. As I said earlier, there's not enough information in the question to be sure if that's happening or not. – Lew Bloch Apr 09 '17 at 08:11
  • 1
    @LewBloch: The variable in question *can't* be uninitialized by the time the referring class takes its value, by definition. I'd be keen to see a counter-example to that statement, given [JLS§12.4.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.1): *"A class or interface type T will be initialized immediately before the first occurrence of any one of the following...A static field declared by T is used and the field is not a constant variable."* – T.J. Crowder Apr 09 '17 at 09:07
0

Static fields are initialized when the class is loaded by the class loader. Default values are assigned at this time. These variables will be initialized first, before the initialization of any instance variables.

vijayraj34
  • 2,135
  • 26
  • 27
  • Again, initialization happens _after_ loading, not during it. This may be the problem here; I strongly suspect that it is. `PAGE_END_objs` might not be initialized at the points where the OP observes the `null`. We don't have enough data from the OP to be sure. – Lew Bloch Apr 08 '17 at 23:54