Newsgroup: it.comp.java
Titolo: Perchè non riesco a comilare un banalissimo programma multimodulo?

Salve, sto cercando di compilare un banalissimo programma multimodulo
senza successo: ho inserito la directory bin di java e la mia
directory di lavoro nel CLASSPATH di windows, separati da ; e ho anche
riavviato per sicurezza, per cui la directory sarà tipo C:\MyProject\
Ora Metto i miei due file .java all'interno di questa directory
mantenendoli al primo livello, cioè senza metterli in sottodirectory.
In teoria il package di default dovrebbe comprendere tutti i file
presenti nella stessa directory ma quando vado a compilare i due file
usando javac nomefile1.java nomefile2.java mi dà errore sui 2 unici
metodi che richiamo nell'altro file (in uno c'è solo il main e
nell'altro ci sono i metodi) dandomi questo errore "cannot find
symbol" a fianco ad ogni metodo.
Dove sbaglio?


Allega i .java quell'errore si presenta anche quando hai sbagliato a
definire la visibiità dei membri.


Allora il main:
public class PopulationMonitor {
    public static void main(String[] args)
    {
    	System.out.println("Uso della funzione allData:");
    	receiveAllData("Z0", "10", "20");
    	stampaAllData();
    }
}
E l'altro file:
import java.util.*;
public class Responsabile
{
	private String codiceArea;
	private String nomeResponsabile;
	private String [][] allData = new String [3][];
	private ArrayList listZona = new ArrayList();
	private ArrayList listInizio = new ArrayList();
	private ArrayList listFine = new ArrayList();
	private String z, ini, fin;
	private static int counter=0;
	private int i,j;
	/**
	 * Constructors
	 */
	//Avrà bisogno di un'area a cui essere assegnato e verosimilmente di
un nome
	//visto che può trattarsi di una persona..
	public Responsabile(String n, String a)
	{
		nomeResponsabile = n;
		codiceArea = a;
	}
	//Costruttore con solo il nome dell'area nel caso si voglia settare
il nome in seguito
	public Responsabile(String a)
	{
		codiceArea = a;
	}
	/**
     * Methods
     */
    //Riceve i dati riguardo il numero di individui presenti in una
zona e li memorizza in un'arrayList
    public void receiveData(String zona, int inizio, int fine)
    {
    	listZona.add(zona);
    	listInizio.add(inizio);
    	listFine.add(fine);
    }
    //Riceve TUTTI i dati riguardo il numero di individui presenti in
ciascuna zona
    public void receiveAllData(String zona, String inizio, String
fine)
    {
    	allData[0][counter] = zona;
    	allData[1][counter] = inizio;
    	allData[2][counter] = fine;
    	counter++;
    }
    /** METODO A (IL PIU' SEMPLICE MA MENO ELEGANTE)
     * Stampa i dati ottenuti dall'array multidimensionale
     * Gli oggetti saranno inseriti così:
     * le i dell'array rappresenta nome_zona, n° iniziale di
individui, n° finale di individui (3 elementi in tutto)
     * le j rappresentano le diverse zone; Esempio:
     * data[0][0] contiene z0, data[0][1] contiene 10, data[0][2]
contiene 20;
     * data[1][0] contiene z1, data[1][1] contiene 13, data[1][2]
contiene 9; ecc..
     */
    public void stampaAllData()
    {
    	if(allData != null) //Banale controllo per verificare che abbia
ricevuto il riferimento dell'array..
    	{
    		System.out.println("Ricevuti i dati da " +counter+ "zone:");
	    	for(j=0; j<allData[0].length; j++) //Questo for viene eseguito n
volte in base al numero di zone
	    	{
	    		System.out.print("Zona=" + allData[0][j] + ", ");
	    		System.out.print("N° iniziale di individui=" + allData[1][j] +
", ");
	    		System.out.print("N° finale di individui=" + allData[2][j] + ";
\n");
	    	}
    	}
    	else
    		System.out.println("Niente stampa! Nessun dato ricevuto!");
    }
    //METODO B (FORSE MIGLIORE)
    //Stampa i dati contenuti negli arraylist (forse la soluzione più
elegante)
    public void stampaData()
    {
    	//banale controllo per vedere se l'arraylist continene qualcosa
    	if( !(listZona.isEmpty()) )
    	{
    		for(i=0; i<listZona.size(); i++)
    		{
    			z = (String) listZona.get(i);
    			ini = (String) listInizio.get(i);
    			fin = (String) listFine.get(i);
    			System.out.println("Zona="+z+", N° iniziale di individui="+ini
+", N° finale di individui="+fin+";");
    		}
    	}
    	else
    		System.out.println("Niente stampa! Nessun dato ricevuto!");
    }
    /**
     * Setta il nome del responsabile
     */
    public void setName(String n)
    {
        nomeResponsabile = n;
    }
}
Mi sembra che la visibilità ci sia, o no?

 }
ecco, il problema e' qua: receiveAllData e stampaAllData non sa da
dove vengono.
perche':

i metodi sono nella classe Responsabile.
quindi provi con Responsabile.receiveAllData() (ma non sono
sicurissimo che funzioni, ad usare i metodi di una classe senza prima
istanziarne un oggetto, anche se ad esempio println viene usato
cosi...dovrei andare a vedere...ok, non va perche' usi variabili
private della classe, quindi se prima non la istanzi queste variabili
non esistono :P)
oppure istanzi Responsabile:
Responsabile r = new Responsabile(nome,area);
e poi usi i metodi:
r.receiveAllData();
r.stampaAllData();
Ciao Jack

E il bello è che se metto il main tutto in un file mi dà questo
errore:
non-static method
receiveAllData(java.lang.String,java.lang.String,java.lang.String)
cannot be referenced from a static context
        receiveAllData("Z0", "10", "20");
non-static method stampaAllData() cannot be referenced from a static
context
        stampaAllData();
Cioè non ho modo di testare nulla.. :-(


Eheeheh quindi la risposta alla mia domanda è "perchè sono un
idiota!" :-D
Hai stra ragione, ho avuto una svista paurosa..

In uno dei metodi che avevo fatto ce n'era uno che era così:
private String [][] allData = new String [3][];
private static int counter=0;
    public void receiveAllData(String zona, String inizio, String
fine)
    {
    	allData[0][counter] = zona;
    	allData[1][counter] = inizio;
    	allData[2][counter] = fine;
    	counter++;
    }
Ovviamente in fase di esecuzione mi da un errore di
NullPointerExceptions, probabilmente perchè non è il modo migliore per
gestire un'array multidimensionale. Ma poichè mi hanno sempre detto
che in questo tipo di array non sono obbligato a definire a priori la
seconda dimensione ma solo la prima, mi chiedevo se fosse possibile
gestire la seconda dimensione dinamicamente, ovvero aggiungendo
dimensioni man mano che mi servono (in pratica quello che volevo fare
dentro al metodo). Esiste un metodo, o una struttura che mi possa
contenere 3 oggetti alla volta per ogni elemento, che faccia già
questo oppure tutte le volte dovrei creare un nuovo array riversare il
contenuto del vecchio dentro al nuovo e distruggere il vecchio?


in questo caso ti conviene usare un array list.
una controllata alle API ogni tanto non fa mai male...

> possibile gestire la seconda dimensione dinamicamente
Certo che puoi.
Gli array di dimensione N non sono altro che array i cui elementi sono
array di dimensione (N-1).
Fermandoci a 2, 
int a[] = new int[3];
crea 
+-----+-----+-----+
|    0|    0|    0|
+-----+-----+-----+
int b[][] = mew int[3][];
crea
+-----+-----+-----+
| null| null| null|
+-----+-----+-----+
a questo punto, prima di poter usare la seconda dimensione devi fare
b[0] = new int[42];
b[1] = new int[0];
b[2] = new int[1];
e  potrai accedere ai  b[0][i] con  i tra  0 e  41 compresi,  a nessun
elemento b[1] (array di dimensione 0) e solo a b[2][0].
La generalizzazione č semplice e va per induzione... :)
-- 
 /\           ___
/___/\_|_|\_|__|___Gian Uberto Lauri_____
  //--\| | \|  |   Integralista GNUslamico
\/                 e coltivatore diretto di Software
A Cesare avrei detto di scrivermi a 
fn...@rat.vg


Ma infatti nell'altro metodo che ho fatto (che è analogo per funzione)
ho usato proprio 3 arraylist per creare una struttura dinamica.. Il
mio era solo un dubbio per capire bene gli array semplici. ;-)

 A Cesare avrei detto di scrivermi a 
f...@rat.vg
Sisi ho capito, grazie! Quindi in ogni caso dovrei sapere a priori la
seconda dimensione per allocare lo sapzio sufficiente, perciò non è
adatto a quello che volevo fare io.
A sto punto però mi verrebbe in mente una cosa: e se creassi un
arraylist ogni volta che richiamo un metodo e gli metto dentro un
array? Tipo così:
private String [] allData;
private ArrayList listZona = new ArrayList();
public void receiveAllData(String zona, String inizio, String fine)
    {
    	allData = new String [3];
    	allData[0] = zona;
    	allData[1] = inizio;
    	allData[2] = fine;
    	listZona.add(allData);
    }
Poi per estrapolare i dati però devo fare un cast esplicito visto le
la get dell'arraylist restituisce un oggetto di tipo Object..
public void stampaAllData()
    {
    		System.out.println("Ricevuti i dati da allData:");
    		for(i=0; i<listZona.size(); i++)
    		{
    			allData = (String []) listZona.get(i);
               	       System.out.print("Zona=" + allData[0] + ", ");
	    		System.out.print("N' iniziale di individui=" + allData[1] + ",
");
	    		System.out.print("N' finale di individui=" + allData[2] + ";
\n");
	    	}
     }
Così sembra funzionare e forse ho risolto l'unione delle due cose.. :-)

 writes:
A> Poi per estrapolare i dati però devo fare un cast esplicito visto le
A> la get dell'arraylist restituisce un oggetto di tipo Object..
Occhio, non ritorna  un oggetto di tipo Object ma  un oggetto che, per
quello  che ne  sa lui  è  di tipo  Object, poi  il tipo  dell'oggetto
dipende dall'oggetto stesso.
-- 
 /\           ___
/___/\_|_|\_|__|___Gian Uberto Lauri_____
  //--\| | \|  |   Integralista GNUslamico
\/                 e coltivatore diretto di Software
A Cesare avrei detto di scrivermi a 
fn...@rat.vg

 A Cesare avrei detto di scrivermi a 
f...@rat.vg
Ah ok, beh comunque il cast esplicito è obbligatorio perchè se no mi
dà errore..
Ho solo un'ultima cosa da chiedere: nel compilare il file contenente i
metodi che ho scritto sopra mi dà quest'errore:
MyClass.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Provo a ricompilare con quell'opzione e:
MyClass.java:41: warning: [unchecked] unchecked call to add(E) as a
member
of the raw type java.util.ArrayList
        listZona.add(zona);
                    ^
MyClass.java:42: warning: [unchecked] unchecked call to add(E) as a
member
of the raw type java.util.ArrayList
        listInizio.add(inizio);
                      ^
MyClass.java:43: warning: [unchecked] unchecked call to add(E) as a
member
of the raw type java.util.ArrayList
        listFine.add(fine);
                    ^
MyClass.java:53: warning: [unchecked] unchecked call to add(E) as a
member
of the raw type java.util.ArrayList
        listZona.add(allData);
                    ^
Mi chiedo cosa ci sia di non sicuro o di non controllato
nell'assegnare un oggetto in un'ArrayList..
E sopratutto non saprei come risolvere il problema (che poi è solo un
warring).. Sapresti darmi una dritta?
Grazie.

 writes:
A> Note: Recompile with -Xlint:unchecked
Usi Java 1.5 ?
-- 
 /\           ___
/___/\_|_|\_|__|___Gian Uberto Lauri_____
  //--\| | \|  |   Integralista GNUslamico
\/                 e coltivatore diretto di Software
A Cesare avrei detto di scrivermi a 
fn...@rat.vg

Ciao! Riusciresti a postare tutto il codice che hai scritto? Perchè
probabilmente l'errore lo da nell'utilizo di membri o campi con
opzione di visibilità non impostata correttamente!