View Full Version : [java] strutture generiche
nuovoUtente86
22-06-2007, 09:55
Treemap<Object,Object> è equivalente alla struttura Treemap senza l' utilizzo dei generici oppure se nella prima si tenta l' inserimento di una sottoclasse di Object si crea un errore?
Treemap<Object,Object> è equivalente alla struttura Treemap senza l' utilizzo dei generici oppure se nella prima si tenta l' inserimento di una sottoclasse di Object si crea un errore?TreeMap<Object,Object> è la versione "generica" del raw type TreeMap usato nelle versioni di Java pre-generics. E la cosa vale ovviamente anche per le altre collezioni.
In un TreeMap<Object,Object> puoi inserire chiavi e valori di qualunque sottotipo di Object (infatti ... sono comunque degli Object).
nuovoUtente86
23-06-2007, 10:48
TreeMap<Object,Object> è la versione "generica" del raw type TreeMap usato nelle versioni di Java pre-generics. E la cosa vale ovviamente anche per le altre collezioni.
In un TreeMap<Object,Object> puoi inserire chiavi e valori di qualunque sottotipo di Object (infatti ... sono comunque degli Object).
quindi alla fine istanziare una struttura con parametro generico Object alla fi fne equivale ad istanziarla in maniera non generica?
Quando vado a utilizzare poi gli elementi sono obbligato a fare il cast?Mi spiego:
LinkedList<Object> lista=new LinkedLIst<Object>();
lista.addFirst(new MiaClasse());
MiaClasse mc=lista.removeFirst(); va bene oppure mi restituisce un tipo Object per cui devo fare
MiaClasse mc=(MiaClasse)lista.removeFirst()
quindi alla fine istanziare una struttura con parametro generico Object alla fi fne equivale ad istanziarla in maniera non generica?Concettualmente sì. Però se stai usando un JDK 5 o superiore, se usi i raw type ti vengono segnalati degli "unchecked warning"
import java.util.*;
class Prova
{
public static void main (String[] args)
{
List list = new ArrayList ();
list.add ("ciao");
}
}
Prova.java:8: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
list.add ("ciao");
^
1 warningIl motivo è semplice: nel framework di Java le classi collection sono diventate generiche (da Java 5 in poi). La classe List è stata dichiarata come List<E> e il metodo add ad esempio è dichiarata come boolean add(E e)
Il compilatore sta solo avvertendo che l'utilizzo di un raw type è "unsafe", insicuro. Perché il compilatore non può più controllare (come invece potrebbe fare usando i generics) che la classe sia usata in modo type safe.
Quando vado a utilizzare poi gli elementi sono obbligato a fare il cast?Mi spiego:
LinkedList<Object> lista=new LinkedLIst<Object>();
lista.addFirst(new MiaClasse());
MiaClasse mc=lista.removeFirst(); va bene oppure mi restituisce un tipo Object per cui devo fare
MiaClasse mc=(MiaClasse)lista.removeFirst()Se usi i generics no, non è necessario fare dei cast.
List<String> list = new ArrayList<String> ();
list.add ("ciao");
String s = list.get (0); // niente cast
Una cosa molto importante è questa: se non ci sono degli unchecked warning, l'utilizzo dei generics è completamente type safe, quindi anche i cast inseriti in automatico dal compilatore non falliscono mai.
Se invece ci sono degli unchecked warning, allora non si può essere più sicuri. È possibile che ci siano dei problemi a tempo di esecuzione in altre parti di codice che magari non c'entrano nulla.
Meglio fare un esempio:
import java.util.*;
class Prova
{
public static void main (String[] args)
{
List<String> list = new ArrayList<String> ();
list.add ("ciao");
List l = list;
l.add (new Integer (123)); // Linea A
String s = list.get (1); // Linea B
}
}Il compilatore segnala un unchecked warning alla linea A. In pratica ti dice solo: guarda che non so se quello che stai facendo è sicuro. Ma in effetti lo fa a runtime senza problemi.
Il problema sbuca alla linea B, che causa una eccezione ClassCastException.
nuovoUtente86
24-06-2007, 01:17
ho provato a compilare l' ultima classe da te postata e guarda che strano log esce:
C:\Users\A\Documents\Prova11.java:7: type List does not take parameters
List<String> list = new ArrayList<String> ();
^
C:\Users\A\Documents\Prova11.java:12: cannot find symbol
symbol : method add(java.lang.Integer)
location: class List
l.add (new Integer (123)); // Linea A
^
.\List.java:4: unexpected type
found : int
required: reference
LinkedList<int> lista=new LinkedList<int>();
^
.\List.java:4: unexpected type
found : int
required: reference
LinkedList<int> lista=new LinkedList<int>();
^
4 errors
Procedura completata con codice di uscita 1
eppure List è un' interfaccia e LinkedList la implementa per cui l' assegnamento è corretto..
ho provato a compilare l' ultima classe da te postata e guarda che strano log esce:
C:\Users\A\Documents\Prova11.java:7: type List does not take parameters
List<String> list = new ArrayList<String> ();
^
C:\Users\A\Documents\Prova11.java:12: cannot find symbol
symbol : method add(java.lang.Integer)
location: class List
l.add (new Integer (123)); // Linea A
^Ahhh .... che strana cosa! Che compilatore Java usi?
.\List.java:4: unexpected type
found : int
required: reference
LinkedList<int> lista=new LinkedList<int>();
^
.\List.java:4: unexpected type
found : int
required: reference
LinkedList<int> lista=new LinkedList<int>();
^
4 errors
Procedura completata con codice di uscita 1Qui ti dice che ha trovato int ma richiede un reference. I tipi parametrici dei generics possono essere solo ed esclusivamente dei reference, mai dei tipi primitivi.
nuovoUtente86
24-06-2007, 11:37
solitamente per i progetti utilizzo Jbuilder oppure eclipse,ma per fare una cosa veloce ho compilato con textpad..
Il compilatore dice che il tuo List non accetta parametri. Significa che sa cosa sia un parametro quindi dev'essere 1.5+
Ci sono due "List" nelle API standard. L'interfaccia java.util.List, che è generica, e la classe java.awt.List, che non lo è.
Prova ad usare il nome pienamente qualificato java.util.List.
nuovoUtente86
24-06-2007, 13:53
javac -version
che dice?
1.6.0
nuovoUtente86
24-06-2007, 13:56
Il compilatore dice che il tuo List non accetta parametri. Significa che sa cosa sia un parametro quindi dev'essere 1.5+
Ci sono due "List" nelle API standard. L'interfaccia java.util.List, che è generica, e la classe java.awt.List, che non lo è.
Prova ad usare il nome pienamente qualificato java.util.List.
è importato solo java.util per cui nn puo esserci conflitto.
Allora cerca il numero dell'esorcista sulle pagine gialle perchè il tuo PC è posseduto dal demonio :D.
nuovoUtente86
24-06-2007, 17:36
ho fatto diversi progetti,anche simulazioni web-service e non ha mai dato problemi sia con i generici che con le interfacce.
Prova a stampare sulla console il tipo di quel "List":
System.out.println(List.class);
subito prima della linea incriminata. Ho provato a compilare questa classe:
public class Main {
private java.awt.List<String> lista = new java.util.ArrayList<String>();
}
e il compilatore (1.6.0_01) mi da lo stesso messaggio:
Main.java:2: type java.awt.List does not take parameters
private java.awt.List<String> lista = new java.util.ArrayList<String>();
Naturalmente ti credo quando dici che hai incluso il package java.util e quindi quel List non è java.awt.List. Il problema dev'essere da qualche altra parte. Comunque prova a usare il nome pienamente qualificato per List:
java.util.List<String>
e vedi cosa ti dice.
Un'improbabilità che m'è venuta in mente: per caso hai un'ide che crea anche applicazioni Java ME? Perchè usando come librerie "bootstrap" per il compilatore javac quelle di Java ME allora avremmo un java.util.List non generico.
nuovoUtente86
26-06-2007, 21:33
compilando con eclipse funziona tutto ok.
Un' altra domanda però non riesco ad eseguire da riga di comando il -Xlin per verificare i warning.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.