Java实现从文件随机读取响应并循环至用户退出的问题排查
Fixing Your Magic 8 Ball Random Response Issue
Let's walk through the problems in your code and fix them up so your Magic 8 Ball works as expected!
Key Issues in the Original Code
- Uninitialized
linesvariable: You declaredObject lines;but never assigned it a value. Trying to accesslines.lengthwill immediately throw aNullPointerException—that's a showstopper right there. - Repeated file reading + exhausted stream: Every time your loop runs, you try to read the file again. But after the first read, the
BufferedReader's pointer is already at the end of the file, so all subsequentreadLine()calls returnnull. That means youranswersarray ends up filled withnullvalues instead of actual responses. - Hardcoded array length: You set
String[] answers = new String[12];which works only if your text file has exactly 12 lines. If you add or remove responses later, this will cause errors. - Potential Scanner input glitches: Without handling whitespace/empty inputs, you might get unexpected behavior when the user enters nothing or just hits enter.
Corrected Code
Here's a revised version that fixes all these issues and adds some quality-of-life improvements:
import java.util.Scanner; import java.util.Random; import java.io.*; import java.util.ArrayList; public class Magic8Ball { public static void main(String[] args) throws IOException { // Read all responses once, store in an ArrayList for easy access ArrayList<String> answers = new ArrayList<>(); // Use try-with-resources to auto-close the reader (safer than manual close) try (BufferedReader input = new BufferedReader(new FileReader("8_ball_responses.txt"))) { String line; while ((line = input.readLine()) != null) { answers.add(line); } } Scanner keyboard = new Scanner(System.in); Random gen = new Random(); char letter; String choice; System.out.println("Welcome to the Magic 8 Ball! Ask your question:"); do { // Trim input to handle accidental spaces/empty lines String ques = keyboard.nextLine().trim(); if (ques.isEmpty()) { System.out.println("Oops, please enter a valid question!"); continue; } // Pick a random response from our preloaded list int finalAns = gen.nextInt(answers.size()); System.out.println("\n" + answers.get(finalAns)); // Ask if user wants to continue, normalize input to lowercase System.out.println("\nDo you have another question? (yes or no):"); choice = keyboard.nextLine().trim().toLowerCase(); // Default to 'n' if user enters nothing letter = choice.isEmpty() ? 'n' : choice.charAt(0); } while (letter != 'n'); System.out.println("Thanks for playing!"); keyboard.close(); } }
What Changed & Why
- Preload responses into an ArrayList: We read the entire file once at the start, storing all lines in an
ArrayList. This avoids the stream exhaustion issue and lets us dynamically use the actual number of responses (no more hardcoded 12!). - Try-with-resources: This syntax automatically closes the
BufferedReaderwhen we're done with it, preventing resource leaks. - Input handling: We trim user input and check for empty strings to avoid weird behavior from accidental whitespace. We also normalize the "yes/no" input to lowercase, so both
Nandnwork, and handle empty input by defaulting to "no". - Removed the broken
linesvariable: We don't need it anymore—answers.size()gives us the exact number of responses we have.
内容的提问来源于stack exchange,提问作者Vanshika Shukla
相关产品推荐
相关产品推荐

