-4

I have made this code, but it seems that it throws a NullPointerException even when it has been set. This is the code (I am aware my code is not future proof or optimised at all. Please do not comment about it). I have tried passing the reference to the method Main, but that doesn't seem to work.

MainTest.java

public class MainTest {
    public static void main(String[] args) {
        for (int i = 0; i < 500; i++) {
            Main main = new Main();
            main.run();
        }
    }
}

Main.java

public class Main {
    Chicken[] chickenList = new Chicken[8388607];
    int counter = 0;

    public void run() {
        for (int i = 0; i < 4; i++) {
            chickenList[counter++] = new Chicken(Chicken.ADULT, this);
        }
        for (int i = 0; i <= 7200; i++) {
            for (Chicken chicken : chickenList) {
                if (chicken != null) {
                    if (chicken.getAdultOrBaby() == Chicken.ADULT) {
                        chicken.layEgg();
                    } else {
                        chicken.hasGrown();
                    }
                } else {
                    break;
                }
            }
        }
        System.out.println(amountOfChickens());
    }

    public void newChicken() {
        chickenList[counter++] = new Chicken(Chicken.CHILD, this);
    }

    public int amountOfChickens() {
        int amount = 0;
        for (Chicken chicken : chickenList) {
            if (chicken != null) {
                amount++;
            } else {
                return amount;
            }
        }
        return amount;
    }
}

Chicken.java

import java.util.Random;

public class Chicken {
    Random random = new Random();
    private int timeAlive;
    private int timeSinceLastEgg;
    private int adultOrBaby;
    private int randomTimer;
    public static final int ADULT = 0;
    public static final int CHILD = 1;
    public static Main caller;

    public Chicken(int adultBaby, Main callers) {
        caller = callers;
        timeAlive = 0;
        timeSinceLastEgg = 0;
        adultOrBaby = adultBaby;
        if (adultOrBaby == ADULT) {
            randomTimer = newRandomTimer();
        }
    }

    public int getAdultOrBaby() {
        return adultOrBaby;
    }

    public void hasGrown() {
        if (++timeAlive == 1200) {
            adultOrBaby = ADULT;
        }
    }

    private int newRandomTimer() {
        return random.nextInt(300);
    }

    public void layEgg() {
        timeAlive++;
        if ((++timeSinceLastEgg) == (300 + randomTimer)) {
            new Egg(caller);
            timeSinceLastEgg = 0;
            randomTimer = newRandomTimer();
        }
    }
}

Egg.java

import java.util.Random;

public class Egg {
    Main caller;
    Random random = new Random();
    private static final int WILL_HATCH = 2;
    private final int WILL_4 = 3;

    public Egg(Main callers) {
        if (random.nextInt(8) == WILL_HATCH) {
            if (random.nextInt(32) == WILL_4) {
                spawn4();
            } else {
                spawn();
            }
        }
        caller = callers;
    }

    private void spawn4() {
        for (int i = 0; i < 4; i++) {
            caller.newChicken();
        }
    }

    private void spawn() {
        caller.newChicken();
    }
}

And this is the output:

Exception in thread "main" java.lang.NullPointerException
        at Egg.spawn(Egg.java:27)
        at Egg.<init>(Egg.java:14)
        at Chicken.layEgg(Chicken.java:40)
        at Main.run(Main.java:13)
        at MainTest.main(MainTest.java:5)
mabdi36
  • 23
  • 7

2 Answers2

1

You set caller after calling spawn(), which requires it to already be set. Set caller before and it should work.

crusy
  • 1,299
  • 2
  • 21
  • 49
0

In this code you call 'spawn()' method and access caller variable before assigning value to caller variable

     public Egg(Main callers) {
    if (random.nextInt(8) == WILL_HATCH) {
        if (random.nextInt(32) == WILL_4) {
            spawn4();
        } else {
            spawn();
        }
    }
    caller = callers;
}