0

I tried to make copy of an object with list of other objects. I came up with solution which threw NullPointerException. After a lot of time spending on it I managed to make it work but I am very confused about the origin of exception. I seek for an logical explanation of described issue.

After changing return type from long to Long everything works fine as described in comment line in code sample.

import java.util.ArrayList;
import java.util.List;

public class JustDontGetItApp {

    public static void main(String[] args) {
        Dog dog1 = new Dog("Max");
        Dog dog2 = new Dog("Buddy");

        AnimalSchelter animalSchelter = new AnimalSchelter("Hope");
        animalSchelter.getAnimals().add(dog1);
        animalSchelter.getAnimals().add(dog2);

        AnimalSchelter copy = animalSchelter.copy();
    }
}

class AnimalSchelter {

    private String name;
    private final List<Animal> animals = new ArrayList<>();

    public AnimalSchelter(String name) {
        this.name = name;
    }

    public AnimalSchelter(AnimalSchelter animalSchelter) {
        name = animalSchelter.getName();
        animalSchelter.getAnimals().stream().map(Animal::copy).forEach(animals::add);
    }

    public AnimalSchelter copy() {
        return new AnimalSchelter(this);
    }

    public String getName() {
        return name;
    }

    public List<Animal> getAnimals() {
        return animals;
    }
}

abstract class Animal {

    private Long id;

    public Animal() {}

    public Animal(Animal animal) {
        id = animal.getId();
    }

    protected abstract Animal copy();

    //LINE long -> Long fixes everything
    public long getId() {
        return id;
    }
}

class Dog extends Animal {

    private String name;

    public Dog(String name) {
        super();
    }

    public Dog(Dog dog) {
        super(dog);
        name = dog.getName();
    }

    @Override
    protected Animal copy() {
        return new Dog(this);
    }

    public String getName() {
        return name;
    }
}
  • When you change the definition of id from Long to long, what happens? Both long and Long work in getId method perfectly? – stuck Feb 23 '19 at 20:23
  • "long -> Long fixes everything" I'll bet that it doesn't really, it just masks the symptom: you've got null `id`s; it's doubtful that's what you *actually* want. – Andy Turner Feb 23 '19 at 20:30
  • 1
    The issue is that you are never assigning a value to the `id` field of `dog1` and `dog2`. Because of autoboxing, the `long getId()` actually returns `id.getLongValue()`, so you get a NPE because `id` is null; if you change the return type to `Long`, you just return `id`, and null is an acceptable value for that. – Andy Turner Feb 23 '19 at 20:34
  • @AndyTurner You have fully satisfied my curiosity. Thanks! – Przemek Krysztofiak Feb 23 '19 at 21:22

0 Answers0