Newsgroup: it.comp.java
Titolo: Alcune domandine da neofita

Ciao,
sono un neofita di Java, quindi mi scuso per le mie banalissime
domande, ma per me importanti.
Ve ne pongo un paio:
- se la mia applicazione contemplasse tre-quattro classi dovrei
compilarle tutte. Ma devo anche eseguirle tutte, con il comando java
(una ad una), o devo eseguire solo quella che ha il metodo main?
- perchè applicazioni che so funzionare (perchè attinte da siti di
corsi universitari, ecc.) nel mio pc mi danno errore?
Grazie

 corsi universitari, ecc.) nel mio pc mi danno errore?
Domanda troppo generica...
NB una delle cose che fa incazzare di pi� l'informatico � quando gli 
dicono "non va" :) bisogna dettagliare!
-- 
bye
DKano

 dicono "non va" :) bisogna dettagliare!
Concordo. Però anche per me è difficile spiegarmi.
Ad esempio: copio il codice della banalissima applicazione "Hello
World": cambio il nome della classe, compilo con "javac
NomeNuovaClasse.java", nessun errore, poi eseguo "java
NomeNuovaClasse": errore, mi viene citato un nome che avevo inserito
in una precedente versione di quel mio file .java e mi dice che non
trova la classe main NomeNuovaClasse.
Se una classe è già compilata e la ricompilo nuovamente, il
file .class non si sovrascrive? O devo rimuoverlo ogni volta? Devo
azzerare qualche memoria (spero non la mia!)... grazie


il nome del file .java e il nome della direttiva class
all'interno dello stesso DEVONO essere uguali, tu
li hai cambiati entrambi?

 ha scritto nel messaggio

Sì. Ad esempio il contenuto di "Gianni.java" è:
package bb200908;
/**
 * The HelloWorldApp class implements an application that
 * simply prints "Hello World!" to standard output.
 */
class Gianni
{
    public static void main(String[] args)
    {
        System.out.println("Hello World!"); // Display the string.
    }
}
Mi restituisce:
Exception in thread "main" java.lang.NoClassDefFoundError: Gianni
(wrong name: bb200908/Gianni)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
        at java.security.SecureClassLoader.defineClass
(SecureClassLoader.java:124)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:
260)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:
301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:
320)
Could not find the main class: Gianni.  Program will exit.

 ha scritto nel messaggio 
news:b44ac939-22bc-42f3-9d61-
elimina la riga:  package bb200908;

 (wrong name: bb200908/Gianni)
In questo caso ï¿œ la direttiva "package" il problema (se si puï¿œ definire
problema...): o la togli prima di compilare, oppure crei una directory
chiamata bb200908 e ci sposti dentro il file Gianni.class, e poi
dall'ESTERNO di bb200908 dai il comando:
java bb200908.Gianni
Se invece elimini la riga con "package", dopo aver compilato la classe
puoi liberamente lanciare
java Gianni
-- 
Scientology: se la conosci la eviti, se la conosci non ti uccide...
http://xenu.com-it.net
 - 
http://xenu.freewinds.cx
 - 
http://www.xenu.net
(per rispondere personalmente leva IlDitoDalCulo)
---> 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0 <---

 java bb200908.Gianni
Vi ringrazio tutti. Così funziona.
Quindi se un'applicazione avesse più classi e le volessi "raggruppare"
in un pacchetto XYZ, dovrei:
- inserire come prima riga: "package XYZ;"
- salvare i file .java nella sottocartella XYZ
- dal livello superiore, rispetto alla cartella XYZ, compilare con
"javac XYZ/*.java"
- infine eseguire: "java XYZ/NomeClasseConMain"
Giusto?
Grazie!

 Grazie!
Si esatto. Chiaramente se hai molte classi ti conviene usare un qualche 
IDE (Eclipse, netbeans, ecc) che gestisce lui il tutto.
NB di solito i package vanno in minuscolo (package xyz) Puoi 
naturalmente avere pi� livelli di raggruppamento (package x.y.z) 
corrispondenti nel filesystem a x/y/z
-- 
bye
DKano

Ringrazio davvero tutti.
Una curiosità: perchè a volte trovo codice in cui non si importa tutto
il pacchetto, ad es.:
import java.io.*; oppure import java.util.*;
ma si specifica la classe utilizzata?. Per caricare in memoria meno
dati?
Se non è un problema di memoria, perchè non importare java.*?
Grazie

 Grazie
import non importa i sub-package
java.*  non vuol dire java.util.*, quindi bisogna importare tutto quello 
che serve.
  Non ho mai capito se l'import delle singole classi invece che "*" 
facesse poi qualche differenza runtime.
-- 
bye
DKano

 facesse poi qualche differenza runtime.
A runtime nessuna differenza, mentre con sorgenti particolarmente
complessi puï¿œ ridurre un pochino i tempi di compilazione (ma ï¿œ proprio
una differenza impercettibile).
Il problema sorge perï¿œ quando *per caso* una classe scritta da te, nel
package che stai sviluppando, ha lo stesso nome di una classe di un
package che hai importato per intero... Lï¿œ allora o importi le singole
classi, oppure scrivi chiaramente il FQN della classe per intero ogni
volta che ti serve.


 import non importa i sub-package java.*  non vuol dire java.util.*, quindi bisogna importare tutto quello che serve.
Quindi chi scrive:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
anzichè:
import java.io.*;
desidera specificare cosa gli serve, dimostrando di essere un
programmatore più efficiente rispetto a chi importa java.io.*. Giusto?
Grazie

 programmatore pi� efficiente rispetto a chi importa java.io.*. Giusto?
Qui si va nel filosofico... ;)
Potresti voler specificare che ti serve genericamente 
java.io
, perch� ne 
usi buona parte, per esempio.
-- 
bye
DKano


Non è questione di voler dimostrare nulla. Ti faccio invece un esempio
pratico e CONCRETISSIMO:
metti che stai facendo una interfaccia grafica usando la libreria
standard (SWING), e vuoi mostrare una lista.
in swing, la classe per fare le liste (simili per intenderci alle
select di html) è java.awt.List.
Ovviamente questa è l'interfaccia grafica. Vorrai metterci qualcosa
dentro, e che cosa meglio di una lista? La classe (è una interfaccia,
ma alla fine il concetto è il medesimo) del Collections Framework è
java.util.List
Se importi java.util.* e java.awt.* e poi dichiari una variabile
List a;
il compilatore non sa (non può sapere) quale delle due classi tu stai
intendendo, questo fino a che non faranno un compilatore con lettura
del pensiero...
A questo punto l'unico modo è usare il Fully Qualified Name, ovvero
scrivere
java.util.List a; nella dichiarazione della variabile.
Ma metti invece che hai bisogno di tutto awt, ma di alcune classi di
util (ma non List)
Anche in questo caso il doppio import potrebbe incasinare tutto,
perché magari scrivi
List a; intendendo una cosa, ma magari l'import ne intende un
altro....
Alla fine quello che si fa è la seguente. Prima si fa un import con *,
e poi si dice all'IDE (io uso Eclipse) di mettere a posto lui gli
import, e lui, per non sbagliare, li scrive espliciti.
Un altra motivazione per evitare l'* è che con l'* guardando il
sorgente il povero programmatore non sa dove andare a trovare la
classe. Scrivendo invece l'import esteso, almeno sa in che package
(magari deve ancora cercare la lib in cui è contenuta, ma almeno è
meglio di nulla....)

 wrote:
Vi ringrazio! Nei prossimi giorni altre domande, grazie!