Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [JAVA 1.5] Errore in una Classe parametrizzata

    Ciao a tutti.
    Mi sto occupando di una classe parametrizzata che si occupa di collezioni di Object.
    Posto delle righe di codice:

    codice:
    public class Set2 <T> {
       private  Vector els;
    
       public Set2() {
         // POST: inizializza this all'insieme vuoto
         els = new Vector();
        }
    
       public boolean equals (T x) {
        // POST: se x non è istanza di Set torna false
        //       altrimenti converti il tipo statico di x ed eseguiequals(set)
          if (!(x instanceof Set)) return false;
          return equals ((Set2<T>)x);
        }
        
        public boolean equals(Set2<T>  s)  {
        //POST: verifica l'uguaglianza tra due insiemi set, independentemente
        //        dall'ordine degli elementi    
         .....
        }
    Ottengo questo errore: name clash, equals <T> in Set2 and equals (java.lang.Object) in java.lang.Object have the same erasure, yet neither overrides the other public class Set2.

    Non capisco di cosa si tratta, qualcuno può aiutarmi? Queste classi parametrizzate mi danno parecchi problemi.
    Altro non ci apparìa che il cielo e l'onda Quando il Saturnio sul veloce legno Sospese in alto una cerulea nube
    Sotto cui tutte intenebrarsi l'acque

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [JAVA 1.5] Errore in una Classe parametrizzata

    Originariamente inviato da LiLyblack
    Ciao a tutti.
    Mi sto occupando di una classe parametrizzata che si occupa di collezioni di Object.
    Posto delle righe di codice:
    Ci sono diverse cose che non vanno.
    Innanzitutto usi i generics, quindi usali anche per parametrizzare il Vector, cioè:

    private Vector<T> els;

    e nel costruttore di Set2:

    els = new Vector<T>();

    Poi hai messo due metodi equals(). Uno prende un Set2<T>, che potrebbe anche andare bene come metodo in overload. Ma l'altro no. Nella classe Object il metodo equals() prende un Object ed è questa la signature che devi usare se vuoi fare l'override di equals().
    Mettendo come parametro T ci sarebbero 3 metodi equals: quello ereditato da Object e i tuoi due. Ma quello ereditato e il tuo che riceve T hanno la stessa erasure, infatti la erasure di T è Object. E le regole di Java lo proibiscono.

    Originariamente inviato da LiLyblack
    Queste classi parametrizzate mi danno parecchi problemi.
    Perché da quello che vedo i generics, l'override e cose del genere non ti sono molto chiari.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Grazie per aver risposto.
    Per quanto riguarda il costruttore, hai ragione, ho postato male.
    Per la equals sono abituata a scrivere due funzioni, una che tratta gli Object, e quindi fa overriding, e una che ha come parametro il tipo specifico con cui sto lavorando, in maniera tale che invocata la equals su un'istanza di Set fa overloading del metodo più adatto, quello che approssima meglio il tipo statico dell'oggetto in input.

    In questo caso, e qui sicuramente non ho le idee chiare, credevo che la funzione
    codice:
    public boolean equals (T x) {..}
    facesse Overriding, visto che T successivamente lo istanzio di tipo Object, ma sicuramente non è così. Perché non è così? Allora come faccio a fare overriding?

    Sui Generici ho diversi problemi, soprattutto perhé non riesco a trovare una trattazione completa di questo argomento (soprattutto sulla sintassi); nemmeno fra i tutorial della Sun. Temo che essendo un argomento abbastanza recente non sia ancora molto consolidato in letteratura.
    Se qualcuno mi sapesse indicare qualche risorsa ne sarei davvero felice.
    Altro non ci apparìa che il cielo e l'onda Quando il Saturnio sul veloce legno Sospese in alto una cerulea nube
    Sotto cui tutte intenebrarsi l'acque

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da LiLyblack
    Per la equals sono abituata a scrivere due funzioni, una che tratta gli Object, e quindi fa overriding, e una che ha come parametro il tipo specifico con cui sto lavorando, in maniera tale che invocata la equals su un'istanza di Set fa overloading del metodo più adatto, quello che approssima meglio il tipo statico dell'oggetto in input.
    Il metodo in overload più specifico in effetti è superfluo, in quanto verrebbe chiamato solo e unicamente se gli passi un Set2 che ha una istanziazione del tipo parametrico che è accettabile per il tipo del reference su cui invochi il metodo equals.
    E complicherebbe le cose se si volesse estendere la tua classe. Ammetti di voler fare una sottoclasse SubSet2 anch'essa parametrica. Che fai .. metti un metodo equals che prende un SubSet2??? Così ce ne sarebbe uno in più.

    Originariamente inviato da LiLyblack
    ma sicuramente non è così. Perché non è così?
    Per via della "erasure". La erasure di una type variable (la tua T) è Object oppure il tipo del bound più a sinistra, se ha dei bound.

    Se tu avessi messo:

    public class Set2 <T extends Number> {

    (per limitare l'uso di Set2 solo con tipi da Number in giù)

    allora la erasure di T sarebbe Number.

    Originariamente inviato da LiLyblack
    Allora come faccio a fare overriding?
    Usando Object come parametro per equals. E comunque non avrebbe senso che tu metta un equals che accetta un T. Se tu avessi un Set2<String> non ha senso che tu verifichi se è uguale a un String.

    Originariamente inviato da LiLyblack
    Sui Generici ho diversi problemi, soprattutto perhé non riesco a trovare una trattazione completa di questo argomento (soprattutto sulla sintassi); nemmeno fra i tutorial della Sun. Temo che essendo un argomento abbastanza recente non sia ancora molto consolidato in letteratura.
    Questo è quello che ho io:
    Java Generics and Collections
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Grazie ancora per aver risposto, in maniera esauriente e prexisa.
    Ho sotituito nella equals T con Object, e in effetti non mi dà problemi. Non vorrei però che in questo modo uscissi da un contesto di parametrizzazione; non è che devo utilizzare il segna posto <?> per indicare un vincolo superiore (cioè Object)? Mi sta venendo il dubbio..

    Se posso, solo un paio di cose:
    nei metodi dell' Iteratore, precisamente nella next, non riesco a scrivere come tipo di ritorno T, sono costretta a definirlo Object, altrimenti ottengo un errore di questo tipo: non static class T cannot be referenced form a static context, public T next() {..}
    Lo stesso metodo, implementato senza tipi generici (che in realtà è identico a quello con i tipi generici se metto come tipo di ritorno di next un Object) non mi dà alcun problema. Perché?


    Compilando, ottengo 2 warning di unchecked conversion, che non avevo mai incontrato prima d'ora; una nella clone() e una nella funzione Iterator <T> elements(). Che cosa sono? E che tipo di implicazioni hanno?

    Codice:
    codice:
    public class Set2 <T> {
        private  Vector <T> els;
        public Set2() { els = new Vector <T>();}
        private Set2 (Vector <T> v) {els = v;} //cost di ausilio
        ....
       public GSet clone() {new  Set2 <T>( (Vector) els.clone() ); //unchecked conversion
       public Iterator <T> elements(){ return new SetGene(this);}
       // e dentro una inner class che implementa Iterator, unchecked conversion
       public Object next() {return s.els.get(n++);} //se sostituisco Object con T ho l'errore di cui sopra
    
    }
    Altro non ci apparìa che il cielo e l'onda Quando il Saturnio sul veloce legno Sospese in alto una cerulea nube
    Sotto cui tutte intenebrarsi l'acque

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da LiLyblack
    Ho sotituito nella equals T con Object, e in effetti non mi dà problemi. Non vorrei però che in questo modo uscissi da un contesto di parametrizzazione; non è che devo utilizzare il segna posto <?> per indicare un vincolo superiore (cioè Object)? Mi sta venendo il dubbio..
    No. Nella classe Object il metodo equals() ha come parametro un Object ed esattamente questo va usato per poter fare l'override.

    Originariamente inviato da LiLyblack
    nei metodi dell' Iteratore, precisamente nella next, non riesco a scrivere come tipo di ritorno T, sono costretta a definirlo Object, altrimenti ottengo un errore di questo tipo: non static class T cannot be referenced form a static context, public T next() {..}
    Lo stesso metodo, implementato senza tipi generici (che in realtà è identico a quello con i tipi generici se metto come tipo di ritorno di next un Object) non mi dà alcun problema. Perché?
    Bisognerebbe vedere meglio il codice della classe che implementa l'iteratore ... il pezzetto di codice che hai scritto non mi dice molto ....

    In genere la classe che implementa l'iteratore si fa appunto con una classe innestata e privata (infatti è poco utile, anzi per nulla utile, che sia visibile all'esterno). Poi se fare una inner-class o una nester-class (static) dipende.
    Se fai una inner-class, allora la type variable T della tua classe Set2 è visibile e in "scope" anche nella inner-class. Se fai una nested-class la type variable non è in scope e quindi devi dichiarare la classe con una nuova type variable, che puoi chiamare anch'essa T ma che non ha nulla a che fare con quella di Set2 e quindi per evitare confusione (!) in genere le si da un altro nome (es. E).

    Vediamo solo un momento il nome del metodo che restituisce l'iteratore. Tu l'hai chiamato elements(). Non è sbagliato di per sé. Ma nel framework di Java, la interfaccia Collection estende Iterable che è una interfaccia con 1 solo metodo: Iterator<T> iterator(). Un oggetto che implementa Iterable può essere il "target" di un ciclo foreach, quindi molto comodo.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Buongiorno.
    Per evitare problemi ho dichiarato la inner class non statica, ma purtroppo periste un problema:
    nella next è presumibile che io debba resituire un tipo T, ma non riesco, perché la get(int) dei Vector resituisce un Object. Come posso render eil mio Object resituito un tipo T?
    codice:
    public Iterator <T> elements(){ return new SetGene(this);}
    private class SetGene implements Iterator {
        private Set2 s; private int n; private T t1;
        public T next() {t1= s.els.get(n); n++; return t1;} //con ritorno dalla get richiede T
        public SetGene(Set2 s){this.s=s; n=0;}
        public boolean hasNext() {return (n< s.els.size());}

    Purtroppo non posso utilizzare l'ietaratore preessistente in Java.
    Altro non ci apparìa che il cielo e l'onda Quando il Saturnio sul veloce legno Sospese in alto una cerulea nube
    Sotto cui tutte intenebrarsi l'acque

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da LiLyblack
    private class SetGene implements Iterator {
    private class SetGene implements Iterator<T> {

    La type variabile T della tua classe Set2 è in "scope" e va usata per dichiarare che implementi Iterator di T.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Vero! Ma continua a dare lo stesso errore sulla next!!
    Altro non ci apparìa che il cielo e l'onda Quando il Saturnio sul veloce legno Sospese in alto una cerulea nube
    Sotto cui tutte intenebrarsi l'acque

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da LiLyblack
    Vero! Ma continua a dare lo stesso errore sulla next!!
    Già certo (e mi sono dimenticato di dirlo prima): Nella classe dell'iteratore, Set2 devi farlo diventare Set2<T>, sia nella variabile di istanza che nel costruttore.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.