Eccezione di puntatore Null, “Tenta di leggere dal campo di un oggetto null riferimento”

Sto facendo un’applicazione in cui l’utente digita in un elenco di attività, e la lista è salvato per un array. Ogni attività dell’array è un’istanza della Assignment classe. Tuttavia, mi sono reso conto che in java non è possibile aggiungere un elemento ad un array dopo l’array viene creato. Così, quello che ho fatto è stato ho creato un array chiamato tasks che consisteva di molti valori null: Assignment[]tasks = {null, null, null, null, null, null, null, null, null, null, null, null};. Quando voglio aggiungere un compito per l’array, è possibile sostituire solo la prossima valore null con l’oggetto. Tuttavia, ho anche bisogno di avere un array di solo i compiti, senza valori null. Così ho creato un array chiamato full_tasks per tutti gli elementi non nulli:

for (Assignment task: tasks) {
    if (task != null) {
        realLength += 1;
    }
}

Assignment[] full_tasks = new Assignment[realLength];

for (int i=0; i <= full_tasks.length - 1; i++) {
        full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}

Così ora, il full_tasks matrice deve essere un array di tutti i compiti, nessuno dei quali sono null, giusto? Tuttavia, quando si esegue l’applicazione, è possibile avviare l’attività, un errore che dice è causato da un null pointer exception:

 Caused by: java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.example.lb.homeworkappv11.Assignment.name' on a null object reference
        at com.example.lb.homeworkappv11.Schedule.sortTasks(Schedule.java:64)

La linea che i punti di errore è:

full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);

Sono ancora del tutto sicuro di quello che un oggetto null riferimento è, ma penso che significa che uno degli elementi di full_tasks matrice è nullo. Sarebbe corretto? E se si, cosa posso fare per assicurarsi che il full_tasks array è solo non null elementi in tasks array?

Grazie mille!

Edit: la funzione di costruzione per la classe di assegnazione è:

public Assignment(String name, int days, int time) {
    this.name = name;
    this.days_due = days;
    this.time = time;
    this.toSortBy = "nothing";
}
Il tuo “nome” variabile all’interno della Assegnazione è null. Puoi postare il codice del costruttore stai usando?
Ho aggiunto il codice di cui sopra
Controllare la mia risposta.

OriginaleL’autore Lucas B | 2015-08-29

6 Replies
  1. 2

    Un null di riferimento è solo che null. Nel codice è tasks[i].name in cui si tenta di chiamare name su tasks[i] così tasks[i] è null.

    C’è uno scenario che posso pensare, per cui il tuo codice sarebbe sicuramente gettare un NullPointerException.
    Così, io assumo la tua attività array può apparire simile a questo:

    tasks = [task0, null, task2, task3, null, task5]

    Poi full_tasks avrà una dimensione di 4, ma

    for (int i=0; i <= full_tasks.length - 1; i++) {
            full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
    }

    lancerà una NPE appena i == 1 perché tasks[1] è null.

    Quindi, se si desidera riempire full_tasks non-null attività di assicurarsi di avere il diritto di indici di tasks.

    Grazie mille! Questa risposta è stata molto utile. Ho modificato il mio ciclo for in modo che si prende solo la non-null elementi, e ora funziona!

    OriginaleL’autore Sascha Kolberg

  2. 1

    Ecco cosa penso

    Si sono trovare il numero di elementi che non sono null. Non sai dove nella matrice thest null‘s.

    Supporre SOLO il primo elemento è null. Così realLength saranno 7. L’ultimo for ciclo viene eseguito da i=0 per i=7. Quando i=0, tasks[i].name tenta di accedere al name campo del primo elemento; ma il primo elemento sembra essere null`. Questo è dove le cose vanno male.

    Soluzione:

    Ci sono un certo numero di soluzioni. Il più efficiente posso pensare utilizza un ArrayList.

    Per aggirare l’utilizzo di matrici, si consiglia di memorizzare gli indici di tutti gli elementi che non sono null. Questo è un modo.

    Qui è un altro:

    for (Assignment task: tasks) {
      if (task != null) {
        realLength += 1;
      }
    }
    Assignment[] full_tasks = new Assignment[realLength];
    int count = 0;
    for (Assignment task: tasks) {
      if (task != null) {
        full_tasks[count] = new Assignment(task.name, tasks.days_due, task.time);
        count++;
      }
    }

    OriginaleL’autore Saud

  3. 0

    Si può pensare di null come qualcosa che non esiste, per esempio, quando si tenta di ottenere task.name, il cui compito è null, ti da errore, perché si tenta di ottenere il nome da alcune di qualcosa che non esiste ancora.

    In realtà ciò che il codice sta facendo ora è verificare quanti non nulli elementi dell’array originale, e cercare di estrarre i extra i primi n elementi della matrice di un nuovo array.

    cioè se l’elenco è {null, null, non-null, non-null}, dispone di 2 camere non-null elemento, tuttavia il codice a torto consente di estrarre l’elenco dei primi 2 elementi che sono {null, null}

    Modifica, per fare quello che vuoi:

    ArrayList<Assignment> fullTaskList = new ArrayList<Assignment>();
    for (Assignment task: tasks) {
        if (task != null) {
            fullTaskList.add(task);
        }
    }
    //optional
    Assignment[] fullTasks = fullTaskList.toArray(new Assignment[fullTaskList.size()]);

    OriginaleL’autore Derek Fung

  4. 0

    Il problema nel codice è qui:

    (tasks[i].name, tasks[i].days_due, tasks[i].time).

    Anche se stai contando le dimensioni reali, ci potrebbe essere qualche valore null, tra cui a causa di ottenere un oggetto null dall’elenco di attività[i].


    Una buona idea per risolvere questo utilizzando un Elenco invece di un Array. Un Elenco può essere aumentato o diminuito, come si desidera, è sufficiente aggiungere o rimuovere un elemento del vostro tipo di oggetto. Per esempio:

    List<Assignment> list = new ArrayList<>();
    Assignment assignment1 = new Assignment(etc.);
    list.add(assignment1);
    list.get(0) //-> returns the Assignment object that you added.

    Quindi è possibile utilizzare list.size() per ottenere la dimensione per sapere quanti elementi ci sono, o per rimuovere l’ultimo elemento. E lei non avrebbe problemi ad aggiungere nuovi elementi alla lista.

    OriginaleL’autore George

  5. 0

    Sembra che si sta tentando di copiare e compatta, la tasks array in full_tasks array (rimozione null elementi), ma si sta facendo questo parzialmente corretto poiché si accede tasks[i] nel secondo loop senza verificare se la sua è null.

    Invece di:

    for (int i=0; i <= full_tasks.length - 1; i++) {
        full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
    }

    si potrebbe scrivere qualcosa di simile a questo:

    for (int i = 0, f = 0; i < tasks.length; i++) {
        if (tasks[i] != null) {
            full_tasks[f] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
            f++;
        }
    }

    Ma poi di nuovo per risolvere il tuo problema originale, per quanto riguarda il fatto che non è possibile aggiungere eventuali elementi di un array, suggerirei di usare un ArrayList invece di una semplice matrice. Questo consente di aggiungere elementi con ArrayList.add(assignment) e rimuovere nuovamente con ArrayList.remove(index).

    OriginaleL’autore Floern

  6. 0

    Sembra come “attività” la lista è vuota. Assicurarsi che il suo ottenere popolate o mettere un controllo di null
    come :

    if(tasks[i] !=null) {
    
    full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due,  tasks[i].time);
    
     }

    OriginaleL’autore Rehman

Lascia un commento