Home > Back-end >  Why am I getting a null pointer exception for my object and how can I fix it? [duplicate]
Why am I getting a null pointer exception for my object and how can I fix it? [duplicate]

Time:10-02

I have a lot of classes working together. I'm testing my Enclosure class, and whenever I call my addAnimals() function, I get a null pointer exception, pointing at my sanctuary object, even if the object is initialized. Does someone know how I can solve this? It's messing up my whole program. Here's my Enclosure class:

import java.util.ArrayList;

public class Enclosure implements Housing{
  private int id;
  private Monkey.Species species;
  private int size;
  private ArrayList<Monkey> monkeys;
  private Monkey newMonkey;
  private PrimateSanctuary sanctuary;

  Enclosure(PrimateSanctuary sanctuary, int id, int size, ArrayList<Monkey> monkeys) {
    this.sanctuary = sanctuary;
    this.id = id;
    this.size = size;
    this.monkeys = monkeys;
  }

  public int getId() {
    return this.id;
  }

  private PrimateSanctuary getSanctuary() {
    return this.sanctuary;
  }

  /**
   * Returns a string, which is the species housed in the housing unit. Returns null if the housing
   * unit is empty.
   */
  public Monkey.Species getMonkeySpecies() {
    if (monkeys != null) {
      Monkey oneMonkey = monkeys.get(0);
      return oneMonkey.getMonkeySpecies();
    }
    else {
      return null;
    }
  }

  /**
   * Returns True if there's room in a housing unit, False otherwise.
   */
  public boolean getAvailability() {
    ArrayList<Monkey> monkeys = getMonkeys();
    int filledSpace = 0;
    if (monkeys != null) {
      for (int i = 0; i < monkeys.size(); i  ) {
        Monkey currentMonkey = monkeys.get(i);
        if (currentMonkey.getSize() < 10) {
          filledSpace  ;
        }
        else if (currentMonkey.getSize() < 20) {
          filledSpace  = 5;
        }
        else {
          filledSpace  = 10;
        }
      }
    }
    int spaceLeft = getSize() - filledSpace;
    if (spaceLeft >= 10) {
      return true;
    }
    else if (spaceLeft >= 5) {
      if (this.newMonkey.getSize() <= 20) {
        return true;
      }
    }
    else if (spaceLeft >= 1) {
      if (this.newMonkey.getSize() <= 10) {
        return true;
      }
    }
    return false;
  }

  public void addAnimal(int id) {
    PrimateSanctuary sanctuary = getSanctuary();
      Animal animal = sanctuary.getAnimal(id);
      ArrayList<Monkey> newMonkeys = this.monkeys;
      newMonkeys.add((Monkey) animal);
      this.monkeys = newMonkeys;
  }

  public int getSize() {
    return this.size;
  }

  ArrayList<Monkey> getMonkeys() {
    return this.monkeys;
  }

}

Here's the getAnimal() method that's called in that file:

class PrimateSanctuary{

public Animal getAnimal(int id) {
    ArrayList<Animal> allAnimals = getAllAnimals();
    System.out.println("Checking for animals");
    if (allAnimals != null) {
      System.out.println("We have some animals!");
      for (int i = 0; i < allAnimals.size(); i  ) {
        if (allAnimals.get(i).getId() == id) {
          return allAnimals.get(i);
        }
      }
    }
    System.out.println("No animals :(");
    return null;
  }
}

Here's my EnclosureTest file:

import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;

import static org.junit.Assert.*;

public class EnclosureTest {
  private Isolation a;
  private Isolation b;
  private Isolation c;
  private Enclosure one;
  private Enclosure two;
  private PrimateSanctuary mySanctuary;
  private ArrayList<Isolation> isolationCages;
  private ArrayList<Enclosure> enclosures;
  private Monkey clarence;
  private Monkey ada;

  @Before
  public void setUp() throws Exception {
    a = new Isolation (1);
    b = new Isolation (2);
    c = new Isolation (3);
    clarence = new Monkey(1, "Clarence", Monkey.Species.SAKI, Monkey.Sex.M, 25, 3,
            4.5, Monkey.FavFood.INSECTS, one);
    ada = new Monkey(3, "Ada", Monkey.Species.SAKI, Monkey.Sex.F, 30, 2,
            7.1, Monkey.FavFood.TREE_SAP, one);
    one = new Enclosure (mySanctuary, 1, 20, null);
    two = new Enclosure (mySanctuary, 2, 60, null);
    isolationCages = new ArrayList<Isolation>();
    enclosures = new ArrayList<Enclosure>();
    mySanctuary = new PrimateSanctuary (1200, isolationCages, enclosures);
  }
  @Test
  public void testAddAnimal() {
    one.addAnimal(3);
    assertEquals(ada, one.getMonkeys());
  }

  @Test
  public void testGetAvailability() {
    one.addAnimal(1);
    one.addAnimal(3);
    assertEquals(false, one.getAvailability());
  }
}

Apologies if this is very messy.

CodePudding user response:

Your sanctuary is not initialized. In your @Before, you pass mySanctuary. Java is pass-by-value, but all non-primitives are references. Thus, you pass the current value of that reference. Which, at that time, is null. That is what you pass. null, The fact that you set mySanctuary to something a few lines later doesn't affect this, as java is pass-by-value (you've already passed that value).

solution: initialize mySanctuary before you use it.

  • Related