views:

121

answers:

8

My code is something like:

public class Foo {
    public int a;
    Bar[] bar = new Bar[10];

    a = bar[0].baz;
}

public class Bar {
    public int b;

    public Bar () { //I tried doing away with this constructor, but that didn't
                    //fix anything
        b = 0;
    }

    public int Baz () {
        //do somthing
    }
}

And I get an error message similar to:

Exception in thread "Foo" java.lang.NullPointerException

at whichever line in Foo I try to call any function or value of the class Bar. How do I prevent bar[] from being null?

EDIT: After some fiddling, I finally got it fixed, thanks everyone! However, I couldn't call the constructor to fix things up; I had to create another function and call that function from Main (in my case, class Foo is actually class Main, if that really matters). My final result:

public class Foo {
    public int a;
    Bar[] bar = new Bar[10];

    public Foo () { //this constructor wasn't called for some reason... I checked this
                    //by using System.out.println... no message was print onscreen
        for (int a = 0; a < bar.length; a++)
            bar[a] = new Bar();
    }

    public static void initializeFoo () {
        for (int a = 0; a < bar.length; a++)
            bar[a] = new Bar();
    }

    public static void Foo () {
        initializeFoo();
        a = bar[0].baz;
    }
}

Anybody want to help me out with that, or am I supposed to create another question? :)

+3  A: 

The reason you're getting a NullPointerException is because of this line:

a = bar[0].baz;

bar[0] does not yet exist.

What's happening is that when a Foo is being initialized, its default initializers run (like the line mentioned above). You construct bar as an array of Bar references, but do not initialize the individual places in the array. If you want them all to be initialized, you need to do something like this:

public Foo() {
    bar = new Bar[10];
    for (int i = 0; i < 10; i++) {
      bar[i] = new Bar();
    }
    a = bar[0].baz;
}
danben
+1  A: 

Try this:

public class Foo 
{
    public int a;
    Bar[] bar = new Bar[10];

    public Foo()
    {
        for (int i = 0; i < 10; ++i)
        {
            this.bar[i] = new Bar();
        }
    }
    a = bar[0].baz();
}

public class Bar 
{
    public int b;


    public int baz() 
    {
        return b;
    }
}
duffymo
the `b = 0` in the constructor is redundant.and hard-coding 10 at two places isn't nice ;)
Bozho
sure, but it's his code. i'm just fixing one problem at a time.
duffymo
just reminding :)
Bozho
+8  A: 
Bar[] bar = new Bar[10];

a = bar[0].baz;

The above creates an array of type Bar, but does not populate it with any actual Bar objects. Arrays of reference types are initialized with null references. You need to do this:

for(int i=0; i<bar.length; i++) {
    bar[i] = new Bar();
}
Michael Borgwardt
thanks! that worked, but for some reason I couldn't get the constructor to get that to work; I had to use that code inside another method
wrongusername
+8  A: 

You have allocate memory for the references by writing this Bar[] bar = new Bar[10]; but who will allocate memory for the array elements? Infact arrays of reference types are initialized with null references.

You need to allocate memory to array elements too:

for(int i=0; i<bar.length; ++i)
   bar[i]=new Bar();
Prasoon Saurav
+1  A: 

Right after Bar[] bar = new Bar[10], your bar array is initialized with null values. So bar[0] contains null and calling bar[0].baz would cause a NullPointerException.

You need to populate your array with a statement like bar[0] = new Bar(). Or

for (int i = 0; i < bar.length; i++) {
    bar[i] = new Bar();
}
huynhjl
+1  A: 

The key issue here is a misunderstanding of array initialization in Java. The initialization of bar[] will be "10 Bar references which are null".

Here is a corrected example (it does not use 10), though it is not very good Java style for other reasons (e.g. public members):

class Foo {
    Bar[] bar = new Bar[] { new Bar(), new Bar() };
    public int a = bar[0].b;
}

public class Bar {
    public int b = 0;

    public static void main(String... args) {
        Foo foo = new Foo();
        System.out.println(foo.a);
    }
}

This example is closer to the true style of Java:

class Foo {
    static final int numBars = 10;
    private Bar2[] bar = new Bar2[numBars];
    private int a;

    public int getA() { return a; }

    public Foo() {
        for (int i = 0; i < numBars; i++) {
            bar[i] = new Bar2(); 
        } 
        a = bar[0].getB();
    }
}

public class Bar2 {
    private int b = 0;
    public int getB() { return b; }

    public static void main(String... args) {
        Foo foo = new Foo();
        System.out.println(foo.getA());
    }
}
Michael Easter
+1  A: 

Many correct answers to work from. Some issues that I think you might have:

  • A constructor for Foo would be Foo() { /* ... */ } not just placing code anywhere in the class.
  • Instead of using a loop yourself, you can use java.util.Arrays.fill(Object[] a, Object val)

Like so:

public class Foo {
    public int a;
    Bar[] bar = new Bar[10];

    Foo() {
        java.util.Arrays.fill(bar, new Bar());
        a = bar[0].baz();
    }
}

Edit: For your updated question, just call new Foo() from your main(...) method. Also, you can't have a static constructor like you do.

mangoDrunk
+1  A: 

Some answers and comments to your code:

The constructor does not get called on its own, you call it activly with the statement new Foo()

Your initializeFoo() method does not compile. The method is static and cannot access a non-static class member (like bar in your case).

And finally, public static void Foo() is not a constructor but a method. A Constructor does not have a return type (void in your case).

Andreas_D