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

    Sapere se una classe generica implementerà o meno un'interfaccia

    Un bel grattacapo

    Come faccio a sapere se una classe generica K implementerà o meno un'interfaccia?

    Mi spiego. Vorrei poter scrivere qualcosa del tipo:

    codice:
    if ( K implementa Comparable )
       fai qualcosa
    else
       fai qualcos'altro
    Ovviamente non funziona "instanceof" perché K non è un riferimento ad un oggetto, ma una classe. Quindi non posso scrivere:

    codice:
    if K istanceof Comparable
    E non funziona nemmeno

    codice:
    K pippo;
    if pippo istanceof Comparable
    Perché il compilatore mi dice che pippo potrebbe non essere istanziata(giustamente). E io non posso certo istanziare una classe generica!

    Ho trovato il comparatore "isAssignableFrom", ma non riesco a passare la fase di compilazione... Questa è la sua sintassi:

    codice:
    if (   Nomeclasse.class.isAssignableFrom( obj.getClass() )    )
    Come vedete ha sempre bisogno di un oggetto e non lavora su due classi.

    Aggiungo che non è il mio caso quello di aggiungere una verifica al momento della dichiarazione della classe, del tipo:

    codice:
    public class NaturalComparator<K extends Comparable>
    Perché non voglio che K implementi necessariamente Comparable. Voglio che il mio programma si comporti in modo diverso a seconda che lo implementi o meno!

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

    Re: Sapere se una classe generica implementerà o meno un'interfaccia

    Originariamente inviato da Iwk_Batterio
    E non funziona nemmeno

    codice:
    K pippo;
    if pippo istanceof Comparable
    Perché il compilatore mi dice che pippo potrebbe non essere istanziata(giustamente).
    Ma questo è un altro discorso (e non centra con instanceof)! Si tratta del fatto che una variabile locale va inizializzata prima di essere usata.

    Originariamente inviato da Iwk_Batterio
    Aggiungo che non è il mio caso quello di aggiungere una verifica al momento della dichiarazione della classe, del tipo:

    codice:
    public class NaturalComparator<K extends Comparable>
    Fino ad adesso hai parlato di K come di "una classe" ma qui K l'hai usato come "type variable". Non è la stessa cosa.

    Se hai una classe puoi usare i metodi di java.lang.Class (isAssignableFrom() in modo specifico) per sapere se implementa Comparable. Se hai solo una type variable, non c'è altro modo che usare instanceof.

    Vuoi che sia più esplicito??

    Esempio: vogliamo sapere se la classe java.util.Date implementa Comparable (sì ... lo sappiamo dal javadoc che la implementa ma vogliamo verificarlo ).

    codice:
    if (Comparable.class.isAssignableFrom(Date.class)) { .... }
    Se quel tuo K è una classe, allora avrai K.class invece di Date.class


    Se invece K è una type variable, allora usi instanceof

    codice:
    import java.util.*;
    
    public class Prova {
        public static void main(String[] args) {
            GenClass<Date> gc = new GenClass<Date>(new Date());
            gc.test();
        }
    }
    
    class GenClass<K> {
        private K obj;
    
        public GenClass(K obj) {
            this.obj = obj;
        }
    
        public void test() {
            if (obj instanceof Comparable) {
                System.out.println("Questa istanza di GenClass ha un oggetto K che implementa Comparable");
            }
        }
    }
    E non si può fare altrimenti. Perché in questo caso K non è una classe!!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Hai ragione!

    Il caso a cui mi riferisco è il secondo (K è un "type variable").

    Però non posso usare l'ultimo frammento di codice che hai postato perché non ho ancora oggetti di quella classe quando effettuo la verifica .

    Insomma il costruttore GenClass() della classe GenClass<K>() da me non ha parametri.

    Com'è possibile? Perché la mia classe GenClass implementa Comparator<K>, va quindi istanziata (e non usata in modo statico) ma non ha parametri di ingresso.

    Come posso fare?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Iwk_Batterio
    Però non posso usare l'ultimo frammento di codice che hai postato perché non ho ancora oggetti di quella classe quando effettuo la verifica .
    Mi spiace allora. instanceof opera su un oggetto.

    Originariamente inviato da Iwk_Batterio
    Perché la mia classe GenClass implementa Comparator<K>
    Non credo che stai intendendo:

    public class GenClass implements Comparator<K> { .... }

    perché in questo caso K deve essere una classe (altrimenti è un errore di compilazione).

    Se avessi:

    public class GenClass<K> implements Comparator<K> { .... }

    allora K è una type variable e sarebbe tecnicamente corretto. Cosa te ne faresti di una classe del genere .... non lo so. E non so dove/come intendi usare K all'interno di GenClass.

    In ogni caso, se non hai un oggetto, non puoi usare instanceof. E non essendo K una classe, nemmeno usare K.class.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Oggi ho parlato con il professore. E' logicamente scorretto il programma, ma non è mio l'errore. E' del libro di testa (e stiamo parlando di Dati e Algoritmi di Goodrich Tamassia - una bibbia)

    public class GenClass<K> implements Comparator<K> { .... }

    allora K è una type variable e sarebbe tecnicamente corretto. Cosa te ne faresti di una classe del genere .... non lo so. E non so dove/come intendi usare K all'interno di GenClass.
    Posto il codice per curiosità, così capisci a cosa mi serve:

    codice:
    	protected static class NaturalComparator<K> implements Comparator<K>
    	{	
    		public int compare(K key1, K key2)
    		{
    			return ( (Comparable<K>) key1).compareTo(key2);	
    		}
    	}
    Ovviamente perché questo codice sia corretto il tipo generico K deve implementare comparable. Io ci impongo un cast ma il compilatore (giustamente) mi dà un warning.

    La creazione di un comparatore generico di default (che funziona quindi come un adattatore, facendo fare il lavoro a compareTo) non è una soluzione elegante se non si conosce la natura degli elementi (in questo caso chiavi) da comparare.

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Iwk_Batterio
    così capisci a cosa mi serve:
    Sì, ho capito benissimo. È chiaramente un Comparator che si basa su Comparable.

    Originariamente inviato da Iwk_Batterio
    Io ci impongo un cast ma il compilatore (giustamente) mi dà un warning.
    È un unchecked cast (giustissimo) ... puoi solo "sopprimerlo" con una apposita annotazione.

    Originariamente inviato da Iwk_Batterio
    non è una soluzione elegante
    Direi che è accettabile.
    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.