PROBLEMA errore Exception in thread "main" java.lang.NullPointerException.... come risolvo?

Pubblicità

Phoenix530

Utente Attivo
Messaggi
303
Reazioni
21
Punteggio
39
salve a tutti

dopo la bellezza di 20 anni mi sto rimettendo a ripassare java in quanto ho la possibilitá di accedere ad un corso gratuito avanzato a scopo assunzione. dal momento che mi hanno chiesto una buona infarinatura base, oggi ho deciso di provare a costruire una piccola rubrica telefonica che acquisisce tramite un oggetto contatto, nome, cognome, numero e indirizzo di 5 persone massimo. queste 5 persone sono rappresentate da un array dell'oggetto persone di classe contatto. il codice é strutturato con un menu di selezione iniziale che in base al numero inserito, dovrebbe far inserire i dati, sovrascriverli in caso di array pieno o stampare tutto a video (almeno per il momento, successivamente vorrei portare tutto su un file per il salvataggio).

il problema attuale del codice che mi sta facendo uscire pazzo, é che dopo aver inserito i dati del primo utente, il software mi restituisce:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Contatto.compilazione(String, String, String, String)" because "persone[a]" is null
at Main.main(Main.java:37)

altra cosa strana é che se non inserisco due volte il comando per l'acquisizione del primo valore, lo script passa direttamente al secondo. vi allego il codice. se qualcuno riuscisse a farmi capire dove sta il problema ve ne sarei grato.

Java:
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int selezione=0;
        String nome="a";
        String cognome="a";
        String numero="a";
        String indirizzo="a";
        int a=0, b=0;
        Contatto[] persone = new Contatto[5];

        do{
            //stampa menu e acquisizione opzione:
            System.out.printf("Rubrica 1.0 \n \n Seleziona l'opzione: \n 1- inserisci contatto \n 2- cerca contatto \n 3- salva contatti \n 4- visualizza rubrica completa \n 5- esci \n\n");
            System.out.printf("inserisci numero opzione:");
            //acquisizione opzione.
            selezione=scan.nextInt();
            System.out.println("hai selezionato:"+selezione);

            switch(selezione) {
                case 1:
                    if(a<5) {
                        System.out.println("nome:");
                        //non capisco perche'lo skippa.
                        nome = scan.nextLine();
                        nome = scan.nextLine();
                        System.out.println("cognome:");
                        cognome = scan.nextLine();
                        System.out.println("numero:");
                        numero = scan.nextLine();
                        System.out.println("indirizzo:");
                        indirizzo = scan.nextLine();
                        //passo dati allóggetto:
                        persone[a].compilazione( nome, cognome, numero, indirizzo);
                        a++;
                    }else {
                        System.out.println("memoria piena. seleziona la casella da sovrascrivere(1-5):");
                        b=a;
                        a = scan.nextInt();
                        //inserimento
                        System.out.println("nome:");
                        //non capisco perche'lo skippa se ne metto 1.
                        nome = scan.nextLine();
                        nome = scan.nextLine();
                        System.out.println("cognome:");
                        cognome = scan.nextLine();
                        System.out.println("numero:");
                        numero = scan.nextLine();
                        System.out.println("indirizzo:");
                        indirizzo = scan.nextLine();
                        //passo dati al costruttore dell'oggetto creato
                        persone[0].compilazione(nome, cognome, numero, indirizzo);
                        a=b;
                    }
                    break;
                case 2:
                    //contatto.ricerca();
                    break;
                case 3:
                    // contatto.salva();
                    break;
                case 4:
                    for(int i=0;i<5;i++) {
                        if(persone[i]!=null)
                            persone[i].visualizzaDati();
                        else
                            System.out.println("contatto vuoto");
                    }
                    break;
                case 5:
                    break;
                default:
                    selezione = 0;
            }

            if(selezione==5)
                System.out.printf("grazie per aver usato la rubrica!");
        }while(selezione!=5);

    }
}

Contatto.java
Java:
public class Contatto {
    private String nome;
    private String cognome;
    private String numero;
    private String indirizzo;

    public Contatto() {
        this.nome = "vuoto";
        this.cognome = "vuoto";
        this.numero = "vuoto";
        this.indirizzo = "vuoto";
    }

    public void compilazione(String nome, String cognome, String numero, String indirizzo) {
        this.nome = nome;
        this.cognome = cognome;
        this.numero = numero;
        this.indirizzo = indirizzo;
    }

    public void visualizzaDati() {
        System.out.printf("nome inserito:" + this.nome);
        System.out.printf("cognome inserito:" + this.cognome);
        System.out.printf("numero inserito:" + this.numero);
        System.out.printf("indirizzo inserito:" + this.indirizzo);
    }


}
 
Ultima modifica da un moderatore:
L'eccezione è dovuto al fatto che crei un array di Contatti di 5 elementi, ma tutti gli elementi sono a NULL. Devi creare un'istanza effettiva di quella classe (ovvero creare un oggetto) per poter richiamare su di esso il metodo.

Ah, invece del visualizzaDati() in Java esiste il metodo toStraing, definito se non erro da Object.

L'errore lo puoi risolvere ad esempio facendo così:
Java:
persone[a] = new Contatto();

aggiungilo prima della chiamata al metodo compilazione().

Ps. consiglio spassionato: non mettere tutto nel main, non è una buona pratica. Usa i metodi/funzioni e le classi (il do while potrebbe per esempio rimanere nel main, ma andrebbero richiamate delle funzioni, ciascuna incaricata di un compito). Dipende anche come e quanto vuoi astrarre il tutto; io per esempio farei una classe Rubrica con un array di 5 Contatto al suo interno.
 
Contatto.java
insomma, non va molto bene
una cosa del genere invece (andrebbero aggiuti i metodi gest/set dei campi, è semplificato)
Java:
class Contatto {
    private String nome;
    private String cognome;
    private String numero;
    private String indirizzo;

    public Contatto() { // fittizio
        super();
    }

    public Contatto(String cognome, String nome, String indirizzo, String numero) {
        this.nome = nome;
        this.cognome = cognome;
        this.indirizzo = indirizzo;
        this.numero = numero;
    }

    @Override
    public String toString() {
        return "Cognome: " + cognome + "   Nome: " + nome + "   Indirizzo: " + indirizzo + "  N. " + numero;
    }
} // FINE classe Contatto

Per i metodi di stampa menu applicazione, lettura di un contatto, stampa della rubrica ti conviene usare delle funzioni statiche da definire nella classe del main, una cosa del genere:
Java:
static void stampaMenu(){
        System.out.println("Scegli l'opzione");
        System.out.println("[1] Inserisci contatto");
        System.out.println("[2] Visualizza contatti");
        System.out.println("[E] Esci\n");
    }
Java:
static Contatto leggiContatto(){
        System.out.println("\n--------------------------");
        System.out.println("Inserimento nuovo contatto");
        System.out.println("--------------------------");
        Scanner sc = new Scanner(System.in);
        System.out.print("Cognome --> ");
        String c = sc.nextLine();
        System.out.print("Nome --> ");
        String n = sc.nextLine();
        System.out.print("Indirizzo --> ");
        String i = sc.nextLine();
        System.out.print("Numero civico --> ");
        String nc = sc.nextLine();
        System.out.println("--------------------------\n");
        return new Contatto(c, n, i, nc);
    }

se fai così il main sarà molto più leggibile
 
insomma, non va molto bene
una cosa del genere invece (andrebbero aggiuti i metodi gest/set dei campi, è semplificato
Java:
class Contatto {
    private String nome;
    private String cognome;
    private String numero;
    private String indirizzo;

    public Contatto() { // fittizio
        super();
    }

    public Contatto(String cognome, String nome, String indirizzo, String numero) {
        this.nome = nome;
        this.cognome = cognome;
        this.indirizzo = indirizzo;
        this.numero = numero;
    }

    @Override
    public String toString() {
        return "Cognome: " + cognome + "   Nome: " + nome + "   Indirizzo: " + indirizzo + "  N. " + numero;
    }
} // FINE classe Contatto

Per i metodi di stampa menu applicazione, lettura di un contatto, stampa della rubrica ti conviene usare delle funzioni statiche da definire nella classe del main, una cosa del genere:
Java:
static void stampaMenu(){
        System.out.println("Scegli l'opzione");
        System.out.println("[1] Inserisci contatto");
        System.out.println("[2] Visualizza contatti");
        System.out.println("[E] Esci\n");
    }
Java:
static Contatto leggiContatto(){
        System.out.println("\n--------------------------");
        System.out.println("Inserimento nuovo contatto");
        System.out.println("--------------------------");
        Scanner sc = new Scanner(System.in);
        System.out.print("Cognome --> ");
        String c = sc.nextLine();
        System.out.print("Nome --> ");
        String n = sc.nextLine();
        System.out.print("Indirizzo --> ");
        String i = sc.nextLine();
        System.out.print("Numero civico --> ");
        String nc = sc.nextLine();
        System.out.println("--------------------------\n");
        return new Contatto(c, n, i, nc);
    }

se fai così il main sarà molto più leggibile
grazie per i consigli. alla fine grazie ad un amico, sono riuscito a capire il perche' dell'errore. dovevo inizializzare i campi dell'array prima dell'acquisizione dei parametri. domani mattina do una pulita al codice secondo i tuoi suggerimenti e provo a implementare una ricerca per cognome all'interno dell'array.
 
dovevo inizializzare i campi dell'array prima dell'acquisizione dei parametri
non è necessario in realtà, anche se da come hai scritto il codice era quello che ti causava ill riferimento null;
l'essenziale è che ci fosse un array i cui elementi fossero di classe Contatto, l'inizializzazione dei singoli elementi dell'array non è necessaria, infatti possono anche essere null
 
Pubblicità
Pubblicità
Indietro
Top