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

    Java Classe Scanner. Problemi di chiusura degli oggetti tipo Scanner

    Ciao a tutti,
    sono nuovo del forum e spero che la discussione che sto aprendo rispetti le norme previste dal regolamento.

    La mia difficoltà che vorrei sottoporvi è questa. Ho sviluppato un codice che calcola gli interessi che maturano su una somma iniziale per un dato interesse e un certo numero di anni. I dati che vengono forniti in input al programma sono proprio la somma iniziale, la percentuale di interesse e il numero di anni.Il metodo leggiDouble2 permette di incamerare la somma iniziale e la percentuale d'interesse verificando che essi si trovino in un determinato range (minimo;massimo). Il metodo leggiInt legge il numero di anni di giacenza della somma iniziale.
    Per acquisire i dati da tastiera ho usato la classe scanner è ho creato l'oggetto tastiera.
    L'esecuzione del programma non da problemi ma il debugger di Eclipse mi segnala due warnings con la scritta "Resource leak: 'tastiera' is never closed".
    Ho fatto una ricerca su internet e ho trovato che, per ovviare a questo problema, alla fine del codice bisogna 'chiudere' l'oggetto di tipo scanner con nomeoggetto.close().
    Ho quindi aggiunto al codice le righe 18 e 45 tastiera.close();
    In effetti i warnings scompaiono ma il il programma durante l'esecuzione va in errore e non funziona più. Mi viene segnalata la seguente eccezione:

    Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.util.Scanner.nextLine(Unknown Source)
    at prova1.leggiDouble2(prova1.java:36)
    at prova1.main(prova1.java:68)

    Potete aiutarmi ? Vorrei lasciare intatta o quasi la struttura del codice, come posso correggere questo tipo di problema ? Ecco il codice:

    codice:
    //import java.io.*;//import java.util.InputMismatchException;
    import java.util.Scanner;
    
    
    public class prova1 {
        
        static int leggiInt(String messaggio)//lettura numero anni di giacenza
        {
            
            System.out.print(messaggio);
            Scanner tastiera = new Scanner(System.in);
            while ( !tastiera.hasNextInt() ) 
            {
               System.out.println("Inserire un *numero INTERO*");
               tastiera.nextLine();  //consumo dato sbagliato
            }
            
            //tastiera.close();
            return tastiera.nextInt();
        }
    
    
        
        
        public static double leggiDouble2(String messaggio, double minimo, double massimo)/*lettura somma iniziale o percentuale interesse*/
        {
            double num=0;
            Scanner tastiera = new Scanner(System.in);
            
            do//controllo tipo di input
            {
                System.out.println(messaggio);
                while (!tastiera.hasNextDouble()) 
                {
                  System.out.println("Inserire un numero!");
                  System.out.println(messaggio);
                  tastiera.nextLine();
                }
                
                num = tastiera.nextDouble();
                
                if (num < minimo || num>massimo)/*verifica se il valore inserito ricade all'interno del range prefissato*/
                  System.out.println("Valore non accettabile ("+minimo+"-"+massimo+")");  
            } while (num < minimo || num>massimo);
            
            //tastiera.close();
            return num;
        }
        
    
    
        
        public static void main(String[] args) {
          // TODO Auto-generated method stub
         
         /* dati input
          *  somma iniziale
          *  percentuale di interesse annuale
          *  numero di anni deposito
          *       
          * */
          
          double sommaIniziale = 0;
          double sommaFinale = 0;
          double percentualeInteresse = 0;
          int anniDeposito = 0;
        
          
          sommaIniziale = leggiDouble2("Inserire somma iniziale: ", 100, 2000);/*chiamata a leggiDouble2*/
          percentualeInteresse = leggiDouble2("Inserire percentuale annuale di interesse: ", 2.5, 10.5);/*chiamata a leggiDouble2*/
          anniDeposito = leggiInt("Durata in anni del deposito: ");/*Chiamata a leggiInt*/
          
          sommaFinale = sommaIniziale;
          while(anniDeposito>0)
          {
              sommaFinale = sommaFinale+ sommaFinale/100 * percentualeInteresse;/*formula per il calcolo dell'interesse composto*/
              anniDeposito = anniDeposito -1;
          }
          
          System.out.println("Hai ora in banca: " + sommaFinale +" euro :)");
          
          System.out.println("Fine programma ...");
        }
    
    
    }

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da NutellaPazza Visualizza il messaggio
    Potete aiutarmi ? Vorrei lasciare intatta o quasi la struttura del codice, come posso correggere questo tipo di problema ?
    Innanzitutto di per sé non è obbligatorio "chiudere" lo Scanner (così come di norma non vanno chiusi esplicitamente System.in/out/err, ci pensa il framework).

    Il warning lo potresti disabilitare globalmente dalle opzioni di Eclipse (sarebbe meglio di no, comunque) oppure solo nel tuo sorgente nel punto esatto del tuo codice con:

    codice:
    @SuppressWarnings("resource")     // Solo da Eclipse 4.2 in poi
    Scanner scanner = new Scanner(System.in);

    Ad ogni modo, se proprio vuoi chiudere lo Scanner, questa dovrebbe essere l'ultima cosa da fare. Quando chiudi lo Scanner, chiude anche lo stream sottostante (System.in). Quindi una volta chiuso non puoi più fare "input".

    Nel tuo codice invece hai "sparpagliato" il tastiera.close(); in più metodi e ovviamente se lo invochi una volta .... non fai più altro. Quindi le soluzioni sono diverse (almeno 2):
    a) Passi ad ognuno dei metodi il riferimento allo Scanner. Nel main lo chiudi solo alla fine.
    b) Invece di usare metodi statici, lavori più "ad oggetti", istanzi la tua classe e tieni lo Scanner come variabile di istanza in modo che sia usabile da più metodi di istanza. Idem fai in modo che lo Scanner sia chiuso solo alla fine.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Grazie per rapidità e la precisione della risposta.
    Ancora non conosco il significato di "metodo statico" e "lavorazione per oggetti". Mi piacerebbe chiedertelo ma temo di andare fuori dal contesto del thread.
    Ho pensato di implentare la prima soluzione, cioè istanzio l'oggetto Scanner nel main e passo il riferimento tastiera agli altri metodi. I warning così non compaiono più e non è stato neanche necessario usare il metodo tastiera.close();
    Sotto il codice modificato seguendo la tua indicazione, grazie ancora andbin:


    codice:
    //import java.io.*;
    //import java.util.InputMismatchException;
    import java.util.Scanner;
    
    public class prova1 {
        
        static int leggiInt(String messaggio, Scanner tastiera)//lettura numero anni di giacenza
        {
            
            System.out.print(messaggio);
            
            while ( !tastiera.hasNextInt() ) 
            {
               System.out.println("Inserire un *numero INTERO*");
               tastiera.nextLine();  //consumo dato sbagliato
            }
            
            //tastiera.close();
            return tastiera.nextInt();
        }
    
        
        
         public static double leggiDouble2(String messaggio, double minimo,  double massimo, Scanner tastiera)/*lettura somma iniziale o percentuale  interesse*/
        {
            double num=0;
            //Scanner tastiera = new Scanner(System.in);
            
            do//controllo tipo di input
            {
                System.out.println(messaggio);
                while (!tastiera.hasNextDouble()) 
                {
                  System.out.println("Inserire un numero!");
                  System.out.println(messaggio);
                  tastiera.nextLine();
                }
                
                num = tastiera.nextDouble();
                
                if (num < minimo || num>massimo)/*verifica se il valore inserito ricade all'interno del range prefissato*/
                  System.out.println("Valore non accettabile ("+minimo+"-"+massimo+")");  
            } while (num < minimo || num>massimo);
            
            //tastiera.close();
            return num;
        }
        
    
        
        public static void main(String[] args) {
        Scanner tastiera = new Scanner(System.in);
          // TODO Auto-generated method stub
         
         /* dati input
          *  somma iniziale
          *  percentuale di interesse annuale
          *  numero di anni deposito
          *       
          * */
          
          double sommaIniziale = 0;
          double sommaFinale = 0;
          double percentualeInteresse = 0;
          int anniDeposito = 0;
        
          
          sommaIniziale = leggiDouble2("Inserire somma iniziale: ", 100, 2000, tastiera);/*chiamata a leggiDouble2*/
           percentualeInteresse = leggiDouble2("Inserire percentuale annuale di  interesse: ", 2.5, 10.5, tastiera);/*chiamata a leggiDouble2*/
          anniDeposito = leggiInt("Durata in anni del deposito: ", tastiera);/*Chiamata a leggiInt*/
          
          sommaFinale = sommaIniziale;
          while(anniDeposito>0)
          {
              sommaFinale = sommaFinale+ sommaFinale/100 * percentualeInteresse;/*formula per il calcolo dell'interesse composto*/
              anniDeposito = anniDeposito -1;
          }
          
          System.out.println("Hai ora in banca: " + sommaFinale +" euro :)");
          
          System.out.println("Fine programma ...");
        }
    
    }

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.