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.