0

I have an inner class that implements Iterable with a method similar to the following:

public Iterator iterator() {
    return new Iterator() {
        Foo foo = fooThreadLocal.get();
        int bar = foo._bar;
        void baz() {
            System.out.println("" + bar);
            System.out.println("" + foo);
        }
        public Object next() {
            baz();
            ...
        }
    }
}

Strangly (to me), in some cases, the value of foo is null inside baz, but the value of bar is 0 (no null pointer exception when the field is initialized). Also, it is strange that the field is null in the first place since if I print a stack trace there is a call to the set method of the ThreadLocal that sets its value with a newly constructed Foo object, but this may be a different problem.

Does anyone know what could be going on here?

jonderry
  • 23,013
  • 32
  • 104
  • 171
  • bar would be 0 if nothing is initialized. So maybe the class doesnt initialize in all cases? – jontro Jun 22 '11 at 23:59
  • what exactly is fooThreadLocal? – Bohemian Jun 23 '11 at 00:02
  • Oh, that makes sense. What's the expected behavior regarding initialization of members of anonymous classes? I was under the impression that the initializers were called when the Object was constructed. – jonderry Jun 23 '11 at 00:02
  • @Bohemian, fooThreadLocal is a ThreadLocal object. – jonderry Jun 23 '11 at 00:03
  • Check this out: http://stackoverflow.com/questions/1371369/about-constructors-in-java . Are you exposing the object in some weird way so that it will be accessible even if it throws a NPE in the constructors? – jontro Jun 23 '11 at 00:06
  • @Bengt I initially thought that but it wouldn't effect the get() returning null. It would effect the internals of Foo which he is not having an issue with. – John Vint Jun 23 '11 at 00:09
  • @John if the get returns null there would be a null pointer exception, which hopefully doesnt make him able to run baz, which is the odd thing in this case. – jontro Jun 23 '11 at 00:10
  • @John V., if the initializers were not being called sometimes, that would explain everything, since bar would be 0 and foo would be null in that case. Also, I have verified that if I re-call `fooThreadLocal.get()` inside `baz()`, the value is not null, as expected. – jonderry Jun 23 '11 at 00:11
  • @jonderry It still looks like one thread creates the iterator and another thread reads from it. Is that correct? – John Vint Jun 23 '11 at 00:13
  • @John V., I don't think so, if that were the only issue, I would expect a null pointer exception to be thrown when the Iterator was being initialized since `int bar = foo._bar;` asks for a field of a null pointer. – jonderry Jun 23 '11 at 00:15
  • What happens if you replace Foo foo = fooThreadLocal.get(); to Foo foo = new Foo(); ? – jontro Jun 23 '11 at 00:18
  • @jonderry Can you declare the foo and bar final? If you can, does the same problem happen. – John Vint Jun 23 '11 at 00:22
  • 1
    OK, I figured it out (finally after hours of debugging). I was calling baz when another field was being initialized. My eyes just skipped over in the stack trace (many times). Ugh... Thanks for all the help though, particularly the observation that what I was seeing was expected behavior if those fields had not been initialized yet. – jonderry Jun 23 '11 at 00:29
  • @jonderry: can you please answer the question yourself and then accept that answer? Also, you need to accept answers to previous questions if they fix your problem. – Zecas May 17 '12 at 09:32

1 Answers1

0

OK, I figured it out (finally after hours of debugging). I was calling baz when another field was being initialized. My eyes just skipped over in the stack trace (many times). Ugh... Thanks for all the help though, particularly the observation that what I was seeing was expected behavior if those fields had not been initialized yet.

jonderry
  • 23,013
  • 32
  • 104
  • 171