PDA

Visualizza versione completa : [Java] Eccezione array di oggetti


GiulioCesare
18-07-2005, 01.07.30
Salve ragazzi ho un problema con un piccolo programma, che eredita una
classe e deve memorizzare delle informazioni tramite input, ma vengono
segnalati degli errori in esecuzione, appena dopo inserisco il primo nome,
l'errore è questo

Exception in thread "main" java.lang.NullPointerException
at studenti.<init>(studenti.java:24)
at studenti.main(studenti.java:42)

E questo è il codice, grazie a chi vorr_ aiutarmi



import javax.swing.*;
import java.util.*;

class dati
{
public String nome="";
public String cognome="";
public int eta=0;
}

public class studenti extends dati
{
public studenti [] n = new studenti [5];

studenti()
{
for(int i=0; i<=4; i++)
{
String t = JOptionPane.showInputDialog("Inserire nome");
n[i].nome = t;
String z = JOptionPane.showInputDialog("Inserire cognome");
n[i].cognome = z;
String y = JOptionPane.showInputDialog("Inserire et_");
n[i].eta = Integer.parseInt(y);
}
}

public void mostra()
{
for(int i=0; i<=4; i++)
{
System.out.println (n[i].nome);
System.out.println (n[i].cognome);
System.out.println (n[i].eta);

}
}

public static void main(String [] args)
{

studenti a = new studenti();
a.mostra();
System.exit(0);

}

}

Dav82
18-07-2005, 01.20.03
Ok, la variabile posta a null la y letta nel parseInt; evidentemente per qualche motivo null: controlla il valore di y prima di darla in pasto a parseInt.

Tra l'altro, una cosa proprio di base... nella classe studenti hai questo attributo:

public studenti [] n = new studenti [5];


sicuro sia una buona scelta? :)
Tra l'altro ti va bene perch semplicemente un contenitore di studenti, se fosse stato tipo

public studenti n = new studenti();

avresti avuto una StackOverflowException, poich la costruzione di un oggetti di tipo studenti richiamava a sua volta la creazione di un altro oggetto dello stesso tipo.

;)

GiulioCesare
18-07-2005, 10.41.51
Le variabili sono a posto, invece l'errore che mi viene dato in esecuzione dopo aver inserito il primo nome proprio quello di StackOverflowException
Sono nuovo del java e questa cosa di inizializzare l'array non l'ho ancora capita, perch dopo aver allocato memoria per l'array, devo anche inizializzare ogni sua posizione? :confused:

Dav82
18-07-2005, 11.21.46
L'array semplicemente il contenitore, come ben sai dal C immagino. Se poi l'array contiene non integer, che sono un tipo primitivo, ma degli oggetti... se utilizzi gli elementi dell'array bisogna seguire le regole per gli oggetti.. ovvero inizializzarli prima dell'uso :)
Creando l'array crei semplicemente dei "puntatori" a degli oggetti, che vanno creati (o che sono gi creati nell'uso del programma... ma prima o poi devono essere stati creati se si vuole usarli).


Se chiami un qualsiasi metodo o leggi un qualsiasi valore di un oggetto non inizializzato otterrai una NullPointerException, poich l'oggetto a cui ti riferisci ancora NULL.


Per la StackOverFlowException funziona cos: tu hai nella classe studenti 1 attributo di tipo studenti, cos quando crei un'istanza dell'oggetto studenti, questo creer anche l'attributo, che ancora di tipo studenti, e quindi bisogna creare un altro oggetto di tipo studenti, che per avr il suo attributo di tipo studenti, e allora un altro oggetto studenti... cos all'infinito, o meglio fino a che la memoria piena: a quel punto parte l'eccezione.

In sostanza una struttura del genere da evitare :)

Prova a pensare ad una soluzione: se te la dico gi io ti perdi met del gusto ;)

GiulioCesare
18-07-2005, 21.58.55
Sono riuscito a farlo funzionare, soprattutto modificando il costruttore studenti e quello della classe dati. Tu parlavi prima del C, io vengo dal C++ ed ho provato ad eseguire lo stesso mio codice in C++ e funziona perfettamente, quindi deduco che in C++ non bisogna istanziare ogni volta ogni singolo elemento dell'array :o

Dav82
18-07-2005, 22.02.53
Sinceramente non lo so, per se non ricordo male in C/C++ lo spazio viene allocato contestualmente alla creazione del contenitore (e in locazioni di memoria attigue, tra l'altro), in base alla dimensione (sizeof) del tipo di dato di cui costituito l'array. Penso che la differenza stia qui :)


Cmq Java bello! :o :p

Thor
18-07-2005, 22.17.48
Originariamente inviato da Dav82
Prova a pensare ad una soluzione: se te la dico gi io ti perdi met del gusto ;)

A questo punto la puoi anche confessare, la soluzione! :D

Dav82
18-07-2005, 22.27.16
Originariamente inviato da Thor
A questo punto la puoi anche confessare, la soluzione! :D

Nu nu!
Fino a che non c' la sua soluzione con il codice, niente suggerimenti :p

GiulioCesare
18-07-2005, 23.07.26
Ecco il mio codice, ditemi se posso modificare ancora qualcosa :)



import javax.swing.*;
import java.util.*;

class dati
{
public String nome="";
public String cognome="";
public int eta=0;

dati(String n, String c, int e)
{

nome=n;
cognome=c;
eta=e;
}
}

public class studenti
{
public dati [] n = new dati [5];

studenti()
{
for(int i=0; i<=4; i++)
{

String t = JOptionPane.showInputDialog("Inserire nome");
String z = JOptionPane.showInputDialog("Inserire cognome");
String y = JOptionPane.showInputDialog("Inserire et");
int x = Integer.parseInt(y);
n[i] = new dati(t, z, x);
}
}

public void mostra()
{
for(int i=0; i<=4; i++)
{
System.out.println (n[i].nome);
System.out.println (n[i].cognome);
System.out.println (n[i].eta);

}
}

public static void main(String [] args)
{

studenti a = new studenti();
a.mostra();
System.exit(0);

}

}

Dav82
18-07-2005, 23.31.49
Cos direi che va bene :)
L'unica cosa mettere visibilit private e non public all'array ;)


Io poi, ma una questione puramente stilistica, visto che un esercizio per imparare, scinderei le operazioni di costruzione dell'oggetto e di inserimento dei dati, ovvero nel costruttore non farei nulla e quello che attualmente nel costruttore lo mettere in un metodo inserimento()... ma ripeto, una questione stilistica :)

Un ultimo appunto (sono rompipalle :D).. anche qui dal punto di vista stilistico... io odio quell'indenting! :D Io lo faccio cos:


public int metodoFuffa(String nome){
//linea vuota che altrimenti non si capisce un tubo
int variabileAppggio = 0; //qui le variabili di servizio
//linea vuota per separare variabili e corpo del metodo
istruzione1
...
istruzioneM
//altra linea vuota per separare corpo e valore di return
return variabileAppoggio;
}

Ma io sono un po' tanto pignolo eh :D

GiulioCesare
18-07-2005, 23.41.03
Per quanto riguarda la programmazione prendo con molta attenzione i tuoi consigli, visto che sono agli inizi con il java, ma per quanto riguarda l'indentazione, odio chi apre la parentesi graffa nella stessa riga del nome del metodo, proprio come fai tu :D