2016-06-24 10 views
2

Ich habe gerade eine 70 Video-Serie auf Java durchlaufen. Zeit, um die Trainingsräder abzunehmen, also mache ich ein sehr einfaches Programm, um 2 Texteingaben für eine Klasse zu machen. Es funktioniert die erste Erstellung einer Car, sondern wirft einen Fehler auf die zweite. Ich kann nicht herausfinden warum.Scanner scheitert an zweiter Klasse lesen

import java.util.Scanner; 

class Car{ 

    public int cost; 
    public double mpg; 

    public void enterInfo() { 
     Scanner reader = new Scanner(System.in); // Reading from System.in 
     System.out.println("Enter cost: "); 
     this.cost = reader.nextInt(); // Scans the next token of the input as an int. 
     System.out.println("Enter MPG: "); 
     this.mpg = reader.nextDouble(); 
     reader.close(); 
    } 




} 

public class App { 

    public static void main(String[] args) { 

     Car car1 = new Car(); 
     car1.enterInfo(); 

     Car car2 = new Car(); 
     car2.enterInfo(); 

     System.out.println(car1.cost); 
    } 

} 

Hier ist der Fehler

Exception in thread "main" java.util.NoSuchElementException 
    at java.util.Scanner.throwFor(Unknown Source) 
    at java.util.Scanner.next(Unknown Source) 
    at java.util.Scanner.nextInt(Unknown Source) 
    at java.util.Scanner.nextInt(Unknown Source) 
    at uda01.Car.enterInfo(App.java:13) 
    at uda01.App.main(App.java:32) 
+3

Verwenden Sie den Scanner ein und 'close' es ganz am Ende – Reimeus

+0

Ah jetzt Sinn machen. –

+0

In Verbindung stehend: http://stackoverflow.com/questions/14962082/close-scanner-without-closing-system-in – Caramiriel

Antwort

1

Das Problem ist, dass Sie den Scanner nach schließen das erste Car Objekt von ihm zu lesen. Wenn Sie das tun, Scannercloses its underlying stream, das heißt System.in:

Wenn dieser Scanner noch nicht dann geschlossen, wenn die zugrunde liegende lesbar auch die Closeable Schnittstelle implementiert dann die Close-Methode des lesbar wird aufgerufen werden.

Deshalb ist der zweite Lesevorgang nicht erfolgreich.

Eine Möglichkeit, dieses Problem zu beheben ist Scanner in Ihrem main zu machen, gibt sie an enterInfo und schließen, sobald die main ist vorbei:

public static void main(String[] args) { 
    Car car1 = new Car(); 
    Car car2 = new Car(); 
    // Try with resource automatically closes your Scanner 
    try(Scanner scanner = new Scanner(System.in)){ 
     car1.enterInfo(scanner); 
     car2.enterInfo(scanner); 
    } 
    System.out.println(car1.cost); 
    System.out.println(car2.cost); 
} 
+0

Sehr geschätzt. –

+1

@TylerRinker Sie sind willkommen! Das ist übrigens ziemlich gut für ein erstes Programm nach einem Videokurs in einer neuen Programmiersprache. Eine Sache, die Sie in Betracht ziehen können, ist die Kombination von 'enterInfo' und' new Car() 'in einer einzigen statischen Methode, so dass Sie 'car car1 = enterInfo (scanner)' und 'new Car()' innerhalb von 'enterInfo' aufrufen könnten . – dasblinkenlight

1

Ich wollte nur mit dasblinkenlight die gleiche Sache sagen. Sie sollten bei jedem Aufruf dieser Methode keinen Scanner erstellen. Ein geeigneterer Weg besteht darin, Scanner as a param zu senden. So können Sie nur Ihren Code aktualisieren:

public class Car { 
    public int cost; 
    public double mpg; 

    public void enterInfo(Scanner reader) { 
     System.out.println("Enter cost: "); 
     this.cost = reader.nextInt(); // Scans the next token of the input as an int. 
     System.out.println("Enter MPG: "); 
     this.mpg = reader.nextDouble(); 
    } 
} 


public class App { 
    public static void main(String[] args) { 
     try (Scanner reader = new Scanner(System.in)) { 
      Car car1 = new Car(); 
      car1.enterInfo(reader); 

      Car car2 = new Car(); 
      car2.enterInfo(reader); 

      System.out.println(car1.cost); 
     } 
    } 
} 
+0

Vielen Dank für die zusätzlichen Informationen. Sehr hilfreich. –