#java
#java
Вопрос:
Я довольно новичок в Java и только учусь, поэтому, пожалуйста, будьте добры. Я выполняю задачу наследования кода и пытаюсь использовать пользовательские данные для настройки автомобиля перед поездкой.
Когда я вызываю 2 метода, которые я использую для установки параметров со сканером, этот первый метод testCar.drivingTest()
работает нормально, однако при testCar.carAgeType()
вызове я получаю исключение.
Ниже приведены запросы и входные данные, а также исключение.
Хотели бы вы протестировать подержанный автомобиль сегодня? : y или n
y
отлично, у вас есть водительские права: тип: большие, средние или маленькие
большой
Отлично, вы сдали свой «большой» экзамен. Давайте проверим MOT: type: pass или fail
передать
Какой тип автомобиля вы искали: спортивный, городской или 4X4
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
at learning.java.Car.carAgeType(Car.java:30)
at learning.java.Main.main(Main.java:17)
Process finished with exit code 1
Из того, что я могу собрать при поиске в Google, большинство людей используют .hasNextLine (), чтобы что-то проверить, но я не знаю, что делать или почему это возвращается как false в testCar.carAgeType . оба метода используют в основном один и тот же код, и когда я вызываю только один из методов testCar.carAgeType или testCar.drivingTest, они отлично работают, когда сами по себе, но при вызове один за другим я получаю исключение. Я также не уверен, что делать, когда я использую .hasNextLine, и он возвращает false.
Кто-нибудь может помочь мне понять, почему сканер выдает исключение, когда он вызывается несколькими методами? Любая помощь очень ценится, спасибо.
Приведенный ниже пример кода содержит main и 2 класса: родительский и дочерний классы Vehicle
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner (System.in);
System.out.println("Would you like to test a used car today? : y or n");
if ("y".equals(scanner.nextLine())){
while (true) {
Car testCar = new Car();
testCar.drivingTest();
testCar.carAgeType();
break;
}
}else{
System.out.println("dang");
}
scanner.close();
}
}
import java.util.Scanner;
public class Vehicle {
private String licence, MOT;
public Vehicle(){
this("null", "null");
}
public Vehicle(String licence, String MOT) {
this.licence = licence;
this.MOT = MOT;
}
public String getLicence() {
return licence;
}
public String getMOT() {
return MOT;
}
public void drivingTest(){
Scanner DTScan = new Scanner (System.in);
System.out.println("great , do you have a driving licence :type: big, medium or small");
String reply = DTScan.nextLine();
if ("big".equals(reply) || "medium".equals(reply) || "small".equals(reply)) {
this.licence = reply;
} else {
this.licence = "fail";
}
System.out.println("Great you passed your '" licence "' exam. Lets check the MOT : type: pass or fail");
reply = DTScan.nextLine();
if ("pass".equals(reply) || "fail".equals(reply)) {
this.MOT = reply;
} else {
this.MOT = "invalid";
}
DTScan.close();
}
}
import java.util.Scanner;
public class Car extends Vehicle{
private String type;
private int age;
public Car(){
}
public Car(String licence, String MOT, String type, int age) {
super(licence, MOT);
this.type = type;
this.age = age;
}
public String getType() {
return type;
}
public int getAge() {
return age;
}
public void carAgeType(){
Scanner ATScan = new Scanner (System.in);
System.out.println("What type of car were you looking for :type: sports , town or 4X4");
ATScan.nextLine();
String reply = ATScan.nextLine();
if ("sports".equals(reply) || "town".equals(reply) || "4X4".equals(reply)) {
this.type = reply;
} else {
this.type = "invalid";
}
System.out.println("And what sort of Age :type: between 1 and 10");
int years = ATScan.nextInt();
if (years > 0 amp;amp; years < 10) {
this.age = years;
} else {
this.age = -1;
}
ATScan.close();
}
}
Комментарии:
1.
while (true) {
и затем безоговорочноbreak
? Пожалуйста, удалите его. Это не служит никакой цели.2. Вы также должны следовать соглашениям об именовании Java: имена переменных и методов записываются в camelCase.
Ответ №1:
class Main34 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Would you like to test a used car today? : y or n");
String val = scanner.nextLine();
if ("y".equals(val)) {
while (true) {
Car testCar = new Car();
testCar.drivingTest(scanner);
testCar.carAgeType(scanner);
break;
}
} else {
System.out.println("dang");
}
scanner.close();
}
}
class Vehicle {
private String licence, MOT;
public Vehicle() {
this("null", "null");
}
public Vehicle(String licence, String MOT) {
this.licence = licence;
this.MOT = MOT;
}
public String getLicence() {
return licence;
}
public String getMOT() {
return MOT;
}
public void drivingTest(Scanner scanner) {
System.out.println("great , do you have a driving licence :type: big, medium or small");
String reply = scanner.nextLine();
if ("big".equals(reply) || "medium".equals(reply) || "small".equals(reply)) {
this.licence = reply;
} else {
this.licence = "fail";
}
System.out.println("Great you passed your '" licence "' exam. Lets check the MOT : type: pass or fail");
reply = scanner.nextLine();
if ("pass".equals(reply) || "fail".equals(reply)) {
this.MOT = reply;
} else {
this.MOT = "invalid";
}
}
}
class Car extends Vehicle {
private String type;
private int age;
public Car() {
}
public Car(String licence, String MOT, String type, int age) {
super(licence, MOT);
this.type = type;
this.age = age;
}
public String getType() {
return type;
}
public int getAge() {
return age;
}
public void carAgeType(Scanner scanner) {
System.out.println("Enter age");
System.out.println("What type of car were you looking for :type: sports , town or 4X4");
String reply = scanner.next();
if ("sports".equals(reply) || "town".equals(reply) || "4X4".equals(reply)) {
this.type = reply;
} else {
this.type = "invalid";
}
System.out.println("And what sort of Age :type: between 1 and 10");
int years = scanner.nextInt();
if (years > 0 amp;amp; years < 10) {
this.age = years;
} else {
this.age = -1;
}
}
}
Вместо создания объекта Scanner для каждого вызова вам просто нужно передать существующий объект scanner в метод.
Также вместо прямой проверки if ("y".equals(scanner.nextLine()))
вам нужно проверить, используя некоторую переменную, подобную этой if ("y".equals(val))
Попробуйте приведенный выше код, он будет работать нормально.
Комментарии:
1. Спасибо, я не был уверен, как вызвать / повторно использовать сканер из другого класса. я знал, что будет простой ответ, но я только в начале своего класса.
Ответ №2:
Проблема возникает из-за того, что вы используете Scanner
with System.in
(который является статическим InputStream
). Всякий раз, когда вы вызываете close()
для Scanner
, он автоматически закрывает базовый, InputStream
в данном случае System.in
. После того, как System.in
она закрыта, никто другой Scanner
не сможет прочитать из нее.
Решение этой проблемы заключается в том, чтобы не закрывать Scanner
в каждой из функций, а делать это только в main
методе.
Ответ №3:
Из документации Oracle по классу Scanner:
Когда сканер закрыт, он закроет свой источник ввода, если источник реализует закрываемый интерфейс.
Это означает, что когда ваш первый метод закрывает сканер, он закрывает также входные данные (System.in ) и именно поэтому вы получаете исключение, а также почему вызов только одного метода не вызывает исключения.
Просто закройте только первый сканер, который у вас есть в вашем главном, и это должно решить вашу проблему.