3
respostas

Nullpointer Exception

Ola a todos. Estou tendo um problema em um trabalho (universidade) que gestiona uma biblioteca. Estou quase no final porque a parte de codificação já esta praticamente terminada porem estou tendo um erro ao tentar retornar os valores das copias dos livros.

Para explicar melhor tenho dois objetos: Resource e Copy. Onde Resource seria o livro em si e Copy uma copia. Cada Resource pode ter até 9 cópias. UML pede assim os construtores: Classe Copy:

  • Copy(resource:Resource)
  • Copy(resource:Resource, location:String) Classe Resource:
  • Resource()
  • Resource (id:String, title:String, imageSrc:String, price: double, yearPublished:int, genre:Genre, loanable:boolean, location:String)

Metodo

public Double getTotalCost() {

        double total = 0;

        try {
            if (getNumCopies() != 0) {
                for (int i = 0; i < copies.length; i++) {
                    if (copies[i] != null)
                        total += copies[i].getResource().getPrice();
                }
            }
        } catch (Exception e) {
            System.out.println(e);
        }

        return total;
    }

O erro esta aqui

total += copies[i].getResource().getPrice();

Esse e o método toString() :

@Override
    public String toString() {
        if (isLoanable() == true) {
            return "ID: " + getId() + "\n" + "Title: " + getTitle() + "\n" + "Published: " + getYearPublished() + "\n"
                    + "Genre: " + getGenre() + "\n" + "Loanable: " + "YES" + "\n" + "Copies: " + getNumCopies() + " ("
                    + getTotalCost() + " €)";
        } else {
            return "ID: " + getId() + "\n" + "Title: " + getTitle() + "\n" + "Published: " + getYearPublished() + "\n"
                    + "Genre: " + getGenre() + "\n" + "Loanable: " + "NO" + "\n" + "Copies: " + getNumCopies() + " ("
                    + getTotalCost() + " €)";
        }
    }

Aqui estão os construtores: Classe Resource:

public Resource() throws ResourceException {
        this("0000000000", "Dummy", "./", 0.0, 1900, Genre.NONFICTION, true, null);
    }
public Resource(String id, String title, String imageSrc, double price, int yearPublished, Genre genre,
            boolean exhibited, String location) throws ResourceException {
        setId(id);
        setTitle(title);
        setImageSrc(imageSrc);
        setPrice(price);
        setYearPublished(yearPublished);
        setLoanable(exhibited);
        setGenre(genre);
    }

Classe Copy:

public Copy(Resource resource) {
        setNumber();
        setResource(resource);
        incNextNumber();
    }

    public Copy(String location, Resource resource) {
        setNumber();
        setLocation(location);
        setResource(resource);
        incNextNumber();
    }
3 respostas

Provavelmente algum resource esta null, ai quando voce invoca o getPrice da nullpointer. Debuga esse for e verifica se dentro de cada copies[i] os resources tem valor

Sim, realmente todos os valores que tento trazer vem um nullPointerException.

System.out.println(copies[i].getResource().getId() + "sou valor  id ");

Imagino que fiz a relação bidirecional um pouco mal nos construtores. Ali no primeiro post tem o UML do exercício na parte de construtores e eles depois implementados por mim.

No UML da classe Resource tenho o método para adicionar uma copia:

  • +addCopy(location:String)

Porem tenho esses dois construtores apenas da classe Copy:

  • +Copy(resource:Resource)
  • +Copy(resource:Resource, location:String)

Meu método de adicionar uma copia esta assim:

public void addCopy(String location) throws ResourceException {

        boolean flag = false;

        for (int i = 0; i < copies.length; i++) {

            if (getNumCopies() >= 9) {
                throw new ResourceException("resource cannot have more than 9 copies!!");
            }

            if (copies[i] == null && flag == false && getNumCopies() <= 9) {
                Copy copy = new Copy(location, new Resource());
                copies[i] = copy;
                flag = true;
            }
        }
    }

Aqui imagino onde esta o meu erro porque não quero salvar um novo Resource e sim a referencia dele.

Copy copy = new Copy(location, new Resource());

Porque a unica classe que o professor passou foi uma para testar o código e ele faz essa seguinte chamada para iniciar um recurso:

public static void main(String[] args) {
        Resource resource1 = null, resource2 = null, resource3 = null;

        try {
            resource1 = new Resource("0000000001", "Fundamentos de Programacion", "./fp.jpg", 20.30, 2015, Genre.STEM,
                    true, "P3-E2");
            resource2 = new Resource("0000000002", "Galaxia 42", "./galaxia42.jpg", 21.55, 2017, Genre.SCIFI, false,
                    "P2-E3");
            resource3 = new Resource("0000000003", "Cocina como en casa", "./cocina.jpg", 16.20, 2013, Genre.HOBBY,
                    true, "P13-E1");
        } catch (ResourceException re) {
            re.printStackTrace();
        }

E depois para adicionar assim:

try {
            resource1.addCopy("P3-E2", resource1);

            System.out.println(System.lineSeparator());
            System.out.println(resource1);
            System.out.println(System.lineSeparator()); 

            System.out.println(System.lineSeparator());
            System.out.println(resource2);
            System.out.println(System.lineSeparator());
            System.out.println(resource3);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Lendo a minha explicação consegui fazer funcionar mas não como esta no UML.

No método addCopy adicionei o parametro Resource:

public void addCopy(String location, Resource resource) throws ResourceException {

        boolean flag = false;

        for (int i = 0; i < copies.length; i++) {

            if (getNumCopies() >= 9) {
                throw new ResourceException("resource cannot have more than 9 copies!!");
            }

            if (copies[i] == null && flag == false && getNumCopies() <= 9) {
                Copy copy = new Copy(location, resource);
                copies[i] = copy;
                flag = true;
            }
        }
    }

E na classe Check do professor passei o resource que ele criou:

resource1.addCopy("P3-E2", resource1);

E claro tudo funciona perfeitamente agora porem imagino que não é assim que o professor queira. Eu não tenho mais ideias... rsrsrs.

Alguma ideia alguém?