Visualizzazione dei risultati da 1 a 8 su 8

Hybrid View

  1. #1
    Grazie andbin.
    Ieri, lavorandoci un pò su, ho tirato fuori questo.
    codice:
    public List<X> readElement(Class<? extends X> cl, String fileName){
            List<X> list = new ArrayList<>();
    
            try (
                    final InputStream file = new FileInputStream (fileName);
                    final InputStream bstream = new BufferedInputStream (file);
                    final ObjectInputStream ostream = new ObjectInputStream (bstream);
                    )
            {
                while (true) {
                    Object obj = ostream.readObject();
                        list.add(cl.cast(obj));
                }
            } catch (EOFException e) {
                System.out.println("Ok: file finito, esce");
            } catch (FileNotFoundException e) {
                System.out.println("Ok: file non trovato, lo crea");
                File f = new File(fileName);
                try {
                    f.createNewFile();
                } catch (IOException e1) {
                    /*Non entra mai qui*/
                    e1.printStackTrace();
                }
            } catch (IOException e) {
                System.out.println("Errore: file corrotto");
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (ClassCastException e) {
                System.out.print("Errore: cast errato");
            }
            
            return list;
            
        }
    Ho deciso, come hai giustamente fatto notare, che era poco intuitivo passare il file, o comunque il path, al costruttore.
    Così. istanziando un solo oggetto della classe, posso scrivere e leggere da qualunque file senza vincoli (mi è venuto il dubbio...non è forse meglio farli statici a sto punto? Al costruttore alla fine non passo nulla)


    Quote Originariamente inviata da andbin Visualizza il messaggio
    public <T> List<T> deserializeItems(Class<T> aClass)
    Ero partito anche io così, ma ho riscontrato un problema.
    Quando vado a istanziare la classe, se provo a passare al metodo una classe diversa da quella utilizzata per la creazione, nemmeno mi compila.
    Per intenderci:
    codice:
    ReaderWriter<Highscore> rw = new ReaderWriter<>();
    rw.readElement(Highscore.class, "miofile.txt"); // fino qui tutto ok
    rw.readElement(ClasseABC.class, "miofile.txt");//non mi compila nemmeno
    Notato questo, sono arrivato alla soluzione sopra (anche se non mi convince troppo).
    Adesso è così:
    codice:
    ReaderWriter<Object> rw = new ReaderWriter<>();
    rw.readElement(Highscore.class, "miofile.txt");
    rw.readElement(ClasseABC.class, "miofile.txt");
    rw.readElement(ClasseABCDEF.class, "miofile.txt");
    Quindi, ricapitolando.
    Così può andare bene o c'è un errore concettuale di fondo? (Il fatto di istanziare la classe come ReaderWriter<Object> mi sembra un "trucco", non una soluzione)
    Però se non scrivo "Object" dovrei istanziare un ReaderWriter per ogni classe, e se devo istanziare un ReaderWriter per ogni classe, inutile che gli passo una classe come parametro
    Sarebbe meglio cambiare facendo diventare tutto statico?
    Grazie
    Ultima modifica di Mirco993; 19-06-2018 a 09:53

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Mirco993 Visualizza il messaggio
    Ieri, lavorandoci un pò su, ho tirato fuori questo.
    Ok ma .. vediamo alcune questioni:

    - meno importante, hai usato X come type variable. Nulla di male o errato ma convenzionalmente si usa T (o E nel caso delle collezioni). O altre lettere in casi più particolari (es. K, V per le map). La X è usata molto raramente (c'è un caso d'uso, in Java 8 la nuova classe Optional ha il orElseThrow che ha una type variable <X extends Throwable> dedicata appunto alla exception).

    - Il ? extends X va bene, così è semplicemente più "ampio". Se passi un Highscore.class, l'inferenza dei tipi permette ad esempio di assegnare ad un List<Object> (perché logicamente qualunque Highscore ci sta in una lista di Object!).
    Senza il extends, se passi Highscore.class, allora devi assegnare ad un List<Highscore> . Tutto qui.

    - La gestione delle eccezioni è un po' fumosa. Sarebbe meglio far uscire l'eccezione fuori dal metodo. E se vogliamo fare i fini, sarebbe anche buono creare una eccezione di più alto livello che incapsula l'eccezione di più basso livello.

    - il fatto di creare il file ... no, non è buono. Non è readElement che dovrebbe occuparsene.

    Quote Originariamente inviata da Mirco993 Visualizza il messaggio
    Ho deciso, come hai giustamente fatto notare, che era poco intuitivo passare il file, o comunque il path, al costruttore.
    No, nel P.S. di prima non dicevo questo! Intendevo che non so (sapevo) come avevi fatto il design della classe e che ci possono essere varie forme possibili.

    Quote Originariamente inviata da Mirco993 Visualizza il messaggio
    Così. istanziando un solo oggetto della classe, posso scrivere e leggere da qualunque file senza vincoli (mi è venuto il dubbio...non è forse meglio farli statici a sto punto? Al costruttore alla fine non passo nulla)

    Ero partito anche io così, ma ho riscontrato un problema.
    Quando vado a istanziare la classe, se provo a passare al metodo una classe diversa da quella utilizzata per la creazione, nemmeno mi compila.
    Per intenderci:
    codice:
    ReaderWriter<Highscore> rw = new ReaderWriter<>();
    rw.readElement(Highscore.class, "miofile.txt"); // fino qui tutto ok
    rw.readElement(ClasseABC.class, "miofile.txt");//non mi compila nemmeno
    Notato questo, sono arrivato alla soluzione sopra (anche se non mi convince troppo).
    Adesso è così:
    codice:
    ReaderWriter<Object> rw = new ReaderWriter<>();
    rw.readElement(Highscore.class, "miofile.txt");
    rw.readElement(ClasseABC.class, "miofile.txt");
    rw.readElement(ClasseABCDEF.class, "miofile.txt");
    Allora qui è meglio chiarire, perché stai facendo confusione.

    Se dichiari la type variable al livello della classe ReaderWriter (che quindi diventa "generica"), va bene, è una scelta possibile. Ma così vai a fissare anche il tipo di ritorno di readElement che è List<X>. Se nell'uso concreto fai un ReaderWriter<Object>, allora vai a fissare che readElement ritorna un List<Object>. Certo ... con lo STESSO oggetto ReaderWriter<Object> puoi invocare readElement con ClasseABC.class e poi un'altra invocazione con ClasseXYZ.class. Ma in uscita hai un List<Object> e questo NON è poi molto utile.

    Se fai un ReaderWriter<Highscore> allora è abbastanza chiaro che quella istanza la dovrai usare solo per leggere oggetti Highscore (quindi List<Highscore>). Per trattare un'altra classe, dovrai creare un'altra istanza, parametrizzata diversamente.
    Se non è questo che vuoi ... non è quello il design giusto!

    Poi c'è anche la questione del filename. Se non lo passi al costruttore, allora le istanze di ReaderWriter a cosa servono? O per dire meglio: due istanze di ReaderWriter in cosa si distinguerebbero e per cosa? Appunto .... Poi magari al momento potrebbero non avere alcun "stato" ma magari in futuro potrebbero avere qualche configurazione o dato specifico per quella istanza.

    Quote Originariamente inviata da Mirco993 Visualizza il messaggio
    Sarebbe meglio cambiare facendo diventare tutto statico?
    Tecnicamente sì, puoi rendere readElement un metodo statico (di "utilità") che è "generico" e riceve il filename.
    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 © 2026 vBulletin Solutions, Inc. All rights reserved.