Visualizzazione dei risultati da 1 a 10 su 12

Discussione: gestione eccezioni

Hybrid View

  1. #1
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Risposte:

    1) No, la "pulizia" del main non c'entra assolutamente. Nel tuo caso, nel main non ci sono blocchi try/catch perchè il codice che tu usi non può in nessun caso lanciare eccezioni checked. L'unico metodo da te usato che può lanciare eccezioni è il metodo aggiungiTesto(String), che però lancia una eccezione unchecked (RuntimeException). Il compilatore guarda solo a cosa tu invochi: se invochi un metodo che dichiara (throws) di poter lanciare eccezioni checked, allora il compilatore ti costringerà ad usare un blocco try/catch o a rilanciare quella/quelle eccezioni dal metodo in cui possono essere sollevate (che sia nel main o in qualunque altro metodo, al compilatore frega nulla).

    2) Premesso che catturare e gestire una NullPointerException nel 99% dei casi non ha alcun senso (preciso dopo), non è vero che tu non puoi creare un oggetto FileSorgente con contenuto nullo. Prova così:


    codice:
    FileSorgente sorg = new FileSorgente("pippo.java", 1, null);

    Questo codice è perfettamente lecito, compila e ti riporta esattamente nel caso in esame.

    3) Il primo metodo, infatti, non gestisce alcuna eccezione, ma semplicemente ne genera una nel caso in cui vi sia quella particolare condizione. E' il chiamante che (a sua discrezione: poichè è una eccezione unchecked) eventualmente dovrà occuparsi di gestirla. Il secondo metodo, al contrario, si occupa di gestire tutte le eventuali eccezioni che possono sollevarsi durante l'esecuzione del codice: quindi lui non delega a nessuno l'onere di gestire eccezioni; fa tutto lui, si arrangia.


    Precisazione sulla NPE (NullPointerException): a parte casi particolari (programmi che, generalmente, analizzano sorgenti o servono ad aiutare le fasi di sviluppo o usano dati provenienti da librerie/programmi di terze parti), una NullPointerException rappresenta un errore nel programma. E un errore non va "gestito": va corretto. Una NPE viene sollevata quando si cerca di usare un oggetto che è nullo. Quando non si è sicuri della reale istanziazione di un oggetto (perchè proviene da codice esterno, di cui non si ha il controllo) ci si dovrebbe fare carico di controllare prima la non nullità del riferimento; se viene sollevata durante l'esecuzione di un programma, allora ci si deve preoccupare di capire perchè quel tale oggetto in quell'istante è nullo. Da questo ne consegue che non ha nessun senso catturare e gestire una NPE.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  2. #2
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Risposte:

    1) No, la "pulizia" del main non c'entra assolutamente. Nel tuo caso, nel main non ci sono blocchi try/catch perchè il codice che tu usi non può in nessun caso lanciare eccezioni checked. L'unico metodo da te usato che può lanciare eccezioni è il metodo aggiungiTesto(String), che però lancia una eccezione unchecked (RuntimeException). Il compilatore guarda solo a cosa tu invochi: se invochi un metodo che dichiara (throws) di poter lanciare eccezioni checked, allora il compilatore ti costringerà ad usare un blocco try/catch o a rilanciare quella/quelle eccezioni dal metodo in cui possono essere sollevate (che sia nel main o in qualunque altro metodo, al compilatore frega nulla).
    Se io modificassi il codice in questo modo:
    codice:
    public class TestFileSorgente {
        public static void main(String args[])
        {
            FileSorgente file = new FileSorgente("File.java",1,"public class TestFileSorgente ");
            System.out.println(file.getContenuto());
            
            try
            {
                file.aggiungiTesto("{");
                System.out.println(file.getContenuto());
            
                file.aggiungiTesto(null);
                System.out.println(file.getContenuto());
            
                file.aggiungiTesto("}",31);
                System.out.println(file.getContenuto());
            
                file.aggiungiTesto("// testo",31);
                System.out.println(file.getContenuto());
            }
            catch(NullPointerException exc)
            {
                System.out.println("problema con: " + exc.getMessage());
            }
            catch(StringIndexOutOfBoundsException exc)
            {
                System.out.println("indice di posizione non valido");
            }
        }
    
    }
    codice:
    import java.lang.String;
    
    public class FileSorgente extends File
    {
    ...
    public String aggiungiTesto(String testo) throws NullPointerException
        {
            if (contenuto == null)
            {
                contenuto = "";
            }
            if (testo == null)
            {
                throw new NullPointerException();
            }
            contenuto += testo;
            return contenuto;
        }
    
    public String aggiungiTesto(String testo, int posizione) throws NullPointerException, StringIndexOutOfBoundsException
        {
            int length = contenuto.length();
            if(contenuto==null)
            {
                contenuto="";
            }
            if(testo==null)
            {
                throw new NullPointerException();
            }
            if(posizione < 0 || posizione > length)
            {
                throw new StringIndexOutOfBoundsException();
            }
            
            contenuto = contenuto.substring(0, posizione) + testo + contenuto.substring(posizione);
            
            return contenuto;
        }
    
    ...
    Sarebbe concettualmente corretto? Dico concettualmente perchè sembra funzionare


    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    2) Premesso che catturare e gestire una NullPointerException nel 99% dei casi non ha alcun senso (preciso dopo), non è vero che tu non puoi creare un oggetto FileSorgente con contenuto nullo. Prova così:

    codice:
    FileSorgente sorg = new FileSorgente("pippo.java", 1, null);

    Questo codice è perfettamente lecito, compila e ti riporta esattamente nel caso in esame.
    ah già, è vero. mi era sfuggito. grazie.
    Avrei una domanda però:
    In questo esempio
    codice:
    public PortaMonete(int... valori)
    {
    ...
    }
    codice:
    public class TestMonete
    {
        public static void main(String args[])
        {
            PortaMonete portamonete3 = new PortaMonete();
        }
    }
    la creazione del portamonete3 senza specificare alcun campo nel costruttore non mi segnala errori perchè ho utilizzato i varargs?


    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Precisazione sulla NPE (NullPointerException): a parte casi particolari (programmi che, generalmente, analizzano sorgenti o servono ad aiutare le fasi di sviluppo o usano dati provenienti da librerie/programmi di terze parti), una NullPointerException rappresenta un errore nel programma. E un errore non va "gestito": va corretto. Una NPE viene sollevata quando si cerca di usare un oggetto che è nullo. Quando non si è sicuri della reale istanziazione di un oggetto (perchè proviene da codice esterno, di cui non si ha il controllo) ci si dovrebbe fare carico di controllare prima la non nullità del riferimento; se viene sollevata durante l'esecuzione di un programma, allora ci si deve preoccupare di capire perchè quel tale oggetto in quell'istante è nullo. Da questo ne consegue che non ha nessun senso catturare e gestire una NPE.


    Ciao.
    Il discorso è chiarissimo. Nell'esempio di sopra l'ho usato per evitare di usare un'eccezione più "generica" (RuntimException) visto che in quel caso era abbastanza chiaro quale tipo di eccezione potesse essere sollevata. Magari però era meglio usare una sola RuntimeException che mi avrebbe gestito anche la StringIndexOutOfBoundsException.
    Ultima modifica di newutente; 19-11-2014 a 11:56

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Quote Originariamente inviata da newutente Visualizza il messaggio
    Se io modificassi il codice in questo modo:
    [...]
    Sarebbe concettualmente corretto? Dico concettualmente perchè sembra funzionare
    Sì, diciamo che "non sarebbe sbagliato". In realtà, essendo che NullPointerException e StringIndexOutOfBoundsException sono eccezioni unchecked, il try/catch risulta comunque un "di più" lasciato a discrezione del programmatore.

    Avrei una domanda però:
    In questo esempio
    codice:
    public PortaMonete(int... valori)
    {
    ...
    }
    codice:
    public class TestMonete
    {
        public static void main(String args[])
        {
            PortaMonete portamonete3 = new PortaMonete();
        }
    }
    la creazione del portamonete3 senza specificare alcun campo nel costruttore non mi segnala errori perchè ho utilizzato i varargs?
    Sì. Nel caso dei varargs il compilatore è in grado di valutare il tipo di chiamata e, quindi, non segnala alcun errore (poichè, effettivamente, non è un errore: numero variabile di argomenti significa, appunto, da 0 argomenti a N argomenti).


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

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.