Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2015
    Messaggi
    37

    Segnaposto limitato inferiormente

    Ciao non ho capito bene cosa accade in questo tipo di esercizio:

    codice:
                    List<? super Number> ln= new ArrayList<>();        
    List<? super Double> ld=new ArrayList<>();
            
            ld=ln; //OK, perchè Number è un supertipo di Double
            
            List<? super Number> lan=new ArrayList<>();
            lan.add(new Double(2.01)); //PERCHE' 
            lan.add(new Object()); //Errore, perchè?
    grazie per l'aiuto

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da iTuring Visualizza il messaggio
    codice:
    List<? super Number> lan=new ArrayList<>();
    lan.add(new Double(2.01)); //PERCHE' 
    lan.add(new Object()); //Errore, perchè?
    Solo guardando la variabile lan, la parametrizzazione concreta esatta non è nota a priori ma si sa solo che è sicuramente qualcosa da Number in su.
    A lan potrebbe essere assegnato un List<Number> oppure un List<Object> e la assegnazione sarebbe lecita.
    Ma solo guardando lan, ripeto, questo non lo sai (e non lo sa nemmeno il compilatore).
    E di conseguenza:

    - un Double ci sta, qualunque sia la parametrizzazione concreta lo può contenere.
    - un Object no, non ci sta .... e se avessi assegnato un List<Number> ? Ovviamente NON può contenere un Object !
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2015
    Messaggi
    37
    Scusa la mia insistenza, ma continuo a non capire. A lan posso aggiungere qualsiasi supertipo di Number, no? Double non è supertipo di Number, mentre Object è supertitpo di Number! Quindi secondo il mio ragionamento aggiungere un Double dovrebbe dar errore mentre aggiungendo un Object non dovrebbe esser un problema dato che è supertitpo di Number.
    cosa sbaglio nel mio ragionamento?

    grazie

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Premessa: nei generics il "wildcard" (il '?') NON indica che un oggetto di una classe generica può contenere qualunque cosa.
    Un List<?> (il wildcard qui è unbounded, senza limite superiore o inferiore) NON vuol dire che la lista può contenere oggetti di qualunque tipo. Vuol dire che la parametrizzazione concreta non è nota a priori guardando solo questa tipizzazione. La parametrizzazione concreta è quella che si mette ad esempio quando si istanzia una implementazione concreta di una lista es. new ArrayList<Qualcosa>(). Qui è quel <Qualcosa> e generalmente è un tipo che esiste realmente es. String, Number, Integer, ecc...
    E quando istanzi una parametrizzazione concreta non puoi usare ? (in nessuna delle forme con o senza bound).

    Prendiamo il tuo esempio:

    List<? super Number> lan;

    poi

    List<Object> lo = new ArrayList<Object>();
    List<Number> ln = new ArrayList<Number>();
    List<Integer> li = new ArrayList<Integer>();


    quindi potrei pensare alle seguenti assegnazioni:

    lan = lo; // OK
    lan = ln; // OK
    lan = li; // NOOOO!!!! Errore

    Perché la terza non è corretta? Semplicemente perché <? super Number> impone un limite inferiore. Ovvero la parametrizzazione concreta che posso assegnare deve essere da Number in sù verso Object. Questo è quanto dice il linguaggio Java.

    Qui non sto parlando del contenuto delle liste! Nel List<Object> lo posso tranquillamente inserire Integer, String, Date ecc... Qui si sta parlando della parametrizzazione concreta che ad un certo punto dovrai di certo usare, perché un oggetto concreto (es. una implementazione di lista) lo dovrai creare per fare qualcosa, no?

    Ora vediamolo con un metodo:

    public static void prova(List<? super Number> lan) { ........ }

    Se io lo invocassi con quel lo:

    prova(lo);

    Tu potresti pensare che all'interno del metodo si possa fare:

    lan.add(new Object());

    perché hai passato un List<Object>. E invece no. Perché vedendo la lista come <? super Number> la parametrizzazione concreta ripeto che non la sai (e nemmeno il compilatore la sa).
    L'unica cosa certa è quel limite inferiore. Qualunque cosa puoi lecitamente passare a 'prova', sicuramente è in grado di contenere un Double. Ma un Object no.

    Se invece invocassi con prova(ln); (quindi passi un List<Number>) e il metodo potesse (idealmente) inserire un new Object() allora ..... tutta la teoria dei generics andrebbe a farsi friggere e non servirebbe a un bel nulla. Perché non sarebbe per niente type-safe.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2015
    Messaggi
    37
    Quindi se ho ben capito, la limitazione di <? super Number> è riferita solo alla parametrizzazione e non sui contenuti della lista. Mentre per quanto riguarda l'aggiunta di un Object non è possibile perchè questo puo' esser qualsiasi tipo e nessuno ci garantisce che sia un numero.

    Ho capito bene?

    mentre in questo caso:

    codice:
    List<? super Number> ln = new ArrayList<Number>(); // 1
    List<? super Double> ld = new ArrayList<Double>(); // 2
    ld = ln; // 3
    ln = new ArrayList<Object>(); // 4
    //ln = ld; // 5 compile error !!
    posso capire che List<? super Number> è super-tipo di List<? super Double> ? Alla riga 5 mi da errore perchè ArrayList<Double>() non è supertipo di ArrayList<Object>()?
    Ultima modifica di iTuring; 08-06-2015 a 14:23

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da iTuring Visualizza il messaggio
    l'aggiunta di un Object non è possibile perchè questo puo' esser qualsiasi tipo e nessuno ci garantisce che sia un numero.
    Sì, non sai quale è la parametrizzazione concreta. Potrebbe essere assegnato es. un List<Object> o un List<Number>. E con questo elemento di "dubbio", non puoi aggiungere oggetti al di sopra di Number ma solo al di sotto (o uguale a Number ma in questo caso essendo abstract non è possibile un oggetto realmente Number).

    Quote Originariamente inviata da iTuring Visualizza il messaggio
    posso capire che List<? super Number> è super-tipo di List<? super Double> ?
    Precisamente List<? super Number> è un sotto-tipo di List<? super Double>. Perché un reference List<? super Number> è assegnabile (è-un) ad un List<? super Double>.
    Qualunque cosa sia la parametrizzazione reale assegnata a List<? super Number> (es. List<Object> o List<Number>) è sicuramente appropriata anche per un List<? super Double>. Il contrario no, non è vero.

    Te lo dico in altro modo: tutto ciò che sta al di sopra di Number è un sotto-insieme di quello che sta al di sopra di Double. Il contrario appunto non è vero.
    Ultima modifica di andbin; 08-06-2015 a 14:48
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2015
    Messaggi
    37
    ok grazie per le risposte, sei stato molto gentile ^_^

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.