|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Bannato
Iscritto dal: Mar 2002
Città: Pescara - 未婚・恋人なし Moto: Honda CBR 1000 RR Casco: XR1000 Diabolic 3
Messaggi: 27578
|
Java 2 SE 5: Considerazioni personali.
Salve a tutti. Oggi stavo pensando a delle questioni che riguardano il linguaggio di programmazione Java e in particolare ad un'aggiunta che e' stata fatta nell'ultima revisione 5.0 del linguaggio nelle specifiche J2SE: i metodi varargs.
Prima di entrare nel merito del mio ragionamento, illustrero' brevemente il concetto di polimorfismo in Java e come esso viene implementato, perche' e' proprio da questo concetto che parte il mio ragionamento. Come in altri linguaggi Object Oriented, uno dei concetti utilizzati per implementare il polimorfismo, e' l'overload delle funzioni, cioe' la possibilita' di dichiarare piu' metodi di classe (funzioni membro per chi conosce C++) con lo stesso nome ma con parametri differenti. Una cosa che bisogna capire dell'overload dei metodi in Java e' come esso venga implementato. Quando viene chiamato un metodo sovraccaricato, il compilatore Java cerca una corrispondenza fra gli argomenti usati per chiamare il metodo e i parametri dichiarati nei metodi. Bisogna notare che la corrispondenza non deve essere necessariamente esatta. Java puo' far affidamento, nella risoluzione di un metodo sovraccaricato, alla sua conversione automatica dei tipi. Per rendere chiaro questo concetto, vi scrivo questo piccolo spezzone di codice: Codice:
class Sovraccarico {
void test()
{
System.out.println("Nessun parametro.");
}
void test(int a, int b)
{
System.out.println("Due parametri: " + a + " " + b);
}
void test(double a)
{
System.out.println("Un solo parametro: " + a);
}
}
class TestSovraccarico {
public static void main(String[] args)
{
Sovraccarico objTest = new Sovraccarico();
int j = 10;
// Chiamata senza parametri.
objTest.test();
// Chiamata con due parametri interi.
objTest.test(23, 54);
// Chiamata con un parametro intero.
objTest.test(j);
// Chiamata con un parametro double.
objTest.test(23.465);
}
}
La terza chiamata, invece, non ha un riscontro come tipo ma se eseguiamo il programma, vediamo che il metodo test() che viene chiamato e' quello che ha come parametro quello double. Il tipo inter j, quindi, viene promosso a double e la risoluzione di overload verificata correttamente e eseguita senza problemi. In Java 2 SE 5.0, (JDK 1.5) e' stata fatta un'interessante aggiunta. I metodi varargs, che consentono di avere una sintassi dedicata per quei metodi che devono utilizzare un numero variabile di argomenti. Prima del JDK 1.5, Java non aveva tale possibilita' e bisognava ricorrere a degli arcani artifici, come ad esempio passare gli argomenti per mezzo di un array. Io ho sempre considerato Java un buon linguaggio che a volte si perde in un bicchier d'acqua. Questa nuova aggiunta, secondo me, non smentisce cio' che penso. La sintassi per i metodi varargs e' la seguente: Codice:
tipo metodo(tipo ... var); Codice:
void test(int ... i); Codice:
i.length del metodo devono essere necessariamente tutti dello stesso tipo. Cosa succede se si vuole dichiarare un metodo che usa parametri variabili ma che non siano tutti dello stesso tipo? Bisogna usare l'overloading dei metodi. Cioe' dichiarare tanti metodi sovraccaricati tante quante sono le permutazioni di argomenti che vogliamo utilizzare. E qui' casca l'asino. Supponiamo di dichiarare due metodi in overload con le seguenti dichiarazioni: Codice:
void test(int ... a); void test(int a, int ... b); ma utilizzare proprio metodi con nomi differenti per evitare ambiguita' di questo genere. Java quindi consente la scrittura di codice ambiguo? Non e' forse questo uno dei principali capisaldi di Java, cioe' la robustezza del codice? Mi viene in mente, a questo punto, il linguaggio C. Tanto criticato, dichiarato obsoleto, eppure, rimane ancora forte dei suoi concetti e metodi ultra testati e ampiamente accettati. Il tipo va_list e le macro va_start() e va_end() per implemetare chiamate con un numero variabile di argomenti... Ultima modifica di mjordan : 20-06-2005 alle 19:38. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2002
Città: Cosenza --> Roma
Messaggi: 853
|
effettivamente la tua riflessione è interessante, anche se poi il compilatore ti segnala questa ambiguità se si verifica, cmq, a parte questa ottima segnalazione di mjordan, penso che java 5.0 sia un'ottimo linguaggio, per gli scopi per i quali è stato studiato.
__________________
GNU MyServer Wants YOU!! We live thinking we will never die. We die thinking we had never lived. Jason Becker |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
Guarda, questa notizia è davvero molto interessante.Comunque, ho da farti una domanda.Come ci sei arrivato? o meglio, come te ne sei accorto?
Non ho ancora provato, ma se questo problema avviene anche per i Costruttori, cosa può succedere?
__________________
My gaming placement |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Jun 2002
Città: Firenze
Messaggi: 630
|
Sicuro che venga compilato?
Data l'ambiguità il compilatore non dovrebbe dare errore? (Sarebbe il comportamento più corretto)
__________________
---> Lombardp CSS Certified Expert (Master Level) at Experts-Exchange Proud user of LITHIUM forum : CPU technology Webmaster of SEVEN-SEGMENTS : Elettronica per modellismo |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Nov 2002
Città: Cosenza --> Roma
Messaggi: 853
|
l'ho provato, se c'è una chiamata al metodo/i in questione che genera l'ambiguità, il compilatore si incavola
__________________
GNU MyServer Wants YOU!! We live thinking we will never die. We die thinking we had never lived. Jason Becker |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
Allora credo che il problema non sussiste più.Se non compila, allora non funziona?
Che ne pensate?
__________________
My gaming placement |
|
|
|
|
|
#7 |
|
Bannato
Iscritto dal: Mar 2002
Città: Pescara - 未婚・恋人なし Moto: Honda CBR 1000 RR Casco: XR1000 Diabolic 3
Messaggi: 27578
|
Come non compila?
A me compila perfettamente e non genera neanche uno straccio di warning |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Nov 2002
Città: Cosenza --> Roma
Messaggi: 853
|
prova.java:19: reference to test is ambiguous, both method test(int,int...) in prova and method test(int...) in prova match
int r=p.test (1,2); ^ 1 error Procedura completata con codice di uscita 1
__________________
GNU MyServer Wants YOU!! We live thinking we will never die. We die thinking we had never lived. Jason Becker |
|
|
|
|
|
#9 | |
|
Bannato
Iscritto dal: Mar 2002
Città: Pescara - 未婚・恋人なし Moto: Honda CBR 1000 RR Casco: XR1000 Diabolic 3
Messaggi: 27578
|
Quote:
1) Puoi postare il codice? 2) L'output di javac -version (a me restituisce javac 1.5.0_02) |
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Nov 2002
Città: Cosenza --> Roma
Messaggi: 853
|
Codice:
public class prova {
public static void test (int a, int ... b) {
int r=a;
for (int i=0; i<b.length; ++i)
r=b[i];
}
public static void test (int ... b) {
int r=0;
for (int i=0; i<b.length; ++i)
r=b[i];
}
public static void main (String [] args) {
p.test (1,2);
}
}
__________________
GNU MyServer Wants YOU!! We live thinking we will never die. We die thinking we had never lived. Jason Becker |
|
|
|
|
|
#11 | |
|
Bannato
Iscritto dal: Mar 2002
Città: Pescara - 未婚・恋人なし Moto: Honda CBR 1000 RR Casco: XR1000 Diabolic 3
Messaggi: 27578
|
Quote:
1) Puoi postare il codice? 2) L'output di javac -version (a me restituisce javac 1.5.0_02) Comunque hai evidenziato un altro aspetto, se penso che hai scritto nel codice quello che credo, poi vi dico Questo codice dovrebbe compilare perfettamente e non emettere warning: Codice:
class Sovraccarico {
void test()
{
System.out.println("Nessun parametro.");
}
void test(int a, int b)
{
System.out.println("Due parametri: " + a + " " + b);
}
void test(double a)
{
System.out.println("Un solo parametro: " + a);
}
void test(double a, double ... b)
{
System.out.println("TADA");
}
}
class TestSovraccarico {
public static void main(String[] args)
{
Sovraccarico objTest = new Sovraccarico();
int j = 10;
double k = 13.45;
objTest.test();
objTest.test(23, 54);
objTest.test(j);
objTest.test(23.465);
objTest.test(k);
}
}
|
|
|
|
|
|
|
#12 |
|
Bannato
Iscritto dal: Mar 2002
Città: Pescara - 未婚・恋人なし Moto: Honda CBR 1000 RR Casco: XR1000 Diabolic 3
Messaggi: 27578
|
Ecco, come temevo
Praticamente nel tuo codice con due metodi overloaded e 2 dichiarazioni varargs, il compilatore emette un errore come dovrebbe essere. Con due metodi overloaded e un solo metodo varargs, il compilatore non riconosce l'ambiguita' e non si degna neanche di generare un warning Cos'e' questo, un'ambiguita' del costrutto o un bug del compilatore? |
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Nov 2002
Città: Cosenza --> Roma
Messaggi: 853
|
scusa, nel tuo codice non vedo dove sia l'ambiguità, se passo due interi, chiama test (int, int);, se passi un double, chiama test (double);, se passi più double (o più interi, ecc), chiama test (double, double ...)
__________________
GNU MyServer Wants YOU!! We live thinking we will never die. We die thinking we had never lived. Jason Becker |
|
|
|
|
|
#14 | |
|
Bannato
Iscritto dal: Mar 2002
Città: Pescara - 未婚・恋人なし Moto: Honda CBR 1000 RR Casco: XR1000 Diabolic 3
Messaggi: 27578
|
Quote:
Codice:
void test(double a)
{
System.out.println("Un solo parametro: " + a);
}
void test(double a, double ... b)
{
System.out.println("TADA");
}
|
|
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: Jun 2002
Città: Firenze
Messaggi: 630
|
Quote:
__________________
---> Lombardp CSS Certified Expert (Master Level) at Experts-Exchange Proud user of LITHIUM forum : CPU technology Webmaster of SEVEN-SEGMENTS : Elettronica per modellismo |
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Nov 2002
Città: Cosenza --> Roma
Messaggi: 853
|
se vogliamo prendere la questione rigorosamente, allora teoricamente ci potrebbe essere un'ambiguità, ma è evidente che il metodo chiamato a runtime è quello che più si avvicina alla lista di parametri passati, io, se devo essere sincero, non ci vedo nessun problema, anche se la tua riflessione è stata molto interessante, poi ho sicuramente meno esperienza di te, quindi potrebbe realmente esserci il problema, io, ripeto, vedo un comportamento molto chiaro e ovvio.
__________________
GNU MyServer Wants YOU!! We live thinking we will never die. We die thinking we had never lived. Jason Becker |
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Jun 2002
Città: Firenze
Messaggi: 630
|
Quote:
__________________
---> Lombardp CSS Certified Expert (Master Level) at Experts-Exchange Proud user of LITHIUM forum : CPU technology Webmaster of SEVEN-SEGMENTS : Elettronica per modellismo |
|
|
|
|
|
|
#18 |
|
Bannato
Iscritto dal: Mar 2002
Città: Pescara - 未婚・恋人なし Moto: Honda CBR 1000 RR Casco: XR1000 Diabolic 3
Messaggi: 27578
|
Il fatto e' che a me ha causato un grosso problema, nel senso che avevo fatto una prototipazione (alla cazzo di cane, lo ammetto) dei metodi overloaded che mi sarebbero potuti servire. Non ho rimosso poi quello a singolo parametro ma avevo realizzato che poteva servirmi una versione a piu' parametri.
Abbiamo appurato che il compilatore fa la scelta giusta (perche come dice giustamente cisc, in caso di ambiguita' bisogna guardare le precedenze) pero', nella mia testa, c'era il metodo varargs che doveva essere eseguito e questo mi ha dato un paio d'ore di grattacapo perche il tutto era dentro una classe piu grossa con delle classi locali, ecc. ecc.) In ogni caso, al di la della precedenza, sarebbe stato piu' giusto emettere almeno un warning, perche' l'ambiguita logica e' palese. Entrambi i metodi sovraccaricati potrebbero essere candidati possibili). In C, per esempio, il compilatore emette un warning quando fai una conversione di tipo automatica senza un casting esplicito. La revisione del 1999 del C standard, ha addirittura eliminato la regola dell'int implicito (cioe' che quando a una funzione non specifichi il tipo di ritorno, viene considerato automaticamente come int). Quindi da un linguaggio come Java mi aspettavo, sinceramente, maggiore "loquacita'". In generale e' considerato "male" avere regole implicite in un linguaggio. Questo modo di operare del compilatore puo' dar vita a dei bug veramente oscuri. Quindi mi aspettavo di piu' da questo costrutto, soprattutto perche' Java ha sempre prediletto la "robustezza del codice" e l'impossibilita' di commettere errori concettuali abbastanza comuni. |
|
|
|
|
|
#19 |
|
Bannato
Iscritto dal: Mar 2002
Città: Pescara - 未婚・恋人なし Moto: Honda CBR 1000 RR Casco: XR1000 Diabolic 3
Messaggi: 27578
|
Che poi, scusate, una piccola provocazione. Ma sto costrutto varargs a parte l'introduzione sintattica, praticamente non ha introdotto niente per semplifucare la gestione dei parametri variabili.
Prima si gestivano comunque con un array passato per argomento, ora passo un intero che viene interpretato comunque come un array... Si, certo, all'occhio e' una sintassi piu' leggibile, ma come versatilita' di programmazione in questo caso rimane identico a prima Ahhhh... Ma forse questa e' carne per Java 1.6 |
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
Adesso io vi faccio una domanda:
public Studente(int matricola, int eta, int esami){} public Studente(int matricola, int eta){} public Studente(int matricola){} .... public static void main(String dati[]){ Studente studente=new Studente(25); .... .... .... } Che cosa SUCCEDE ?
__________________
My gaming placement |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 00:29.











SUCCEDE








