Java User Input with Scanner
Read values supplied outside your source code. Learn what Scanner consumes, how input boundaries affect the result, and how a small retry workflow can reject bad attempts without crashing or looping forever.
Before you start: complete Java Math and review boolean guards. This lesson previews small if, while, and try/catch blocks so invalid-input handling is explained rather than omitted. Those constructs have dedicated lessons later.
What you will be able to do
- Provide a complete input stream before running a lesson example.
- Distinguish token reads from full-line reads.
- Explain and repair the nextInt/nextLine leftover-line problem.
- Separate a parseable number from an acceptable domain value.
- Handle blank, invalid, out-of-range, and exhausted input deliberately.
- Trace a finite retry loop and produce a result only after valid input.
Input is a stream, not a value magically attached to a prompt
Earlier examples used values written in the source. User input lets a running program read values supplied separately. System.in is the standard input stream. A Scanner reads from that stream and can interpret text as lines or numeric tokens. Printing Name? does not itself read, validate, or store a name.
In a normal terminal, a read may wait while you type. This lesson runner is different: edit all the standard-input text before selecting Run. The server supplies that text to the program and then ends the stream. You cannot type a reply into the output panel after execution begins. Each example's input is prefilled and its input panel opens automatically.
The output panel does not automatically echo the supplied input. You will see the program's prompt and printed results, not an inserted copy of what you entered. Reset restores both the original source and the original input. Try changing only the name before running the greeting; that separates a source-code change from an input-data change.
Main.java · Read a complete name
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Name?
Hello, Mina Ben Ali!
Try a full-name change
Replace the input with Sami Ben Ali and run unchanged source. Only the greeting should change. Clear the input entirely and run the unguarded greeting to observe NoSuchElementException; the guarded examples below show how to handle missing input.
Read the Scanner setup before following its methods
import java.util.Scanner makes the class name available. new Scanner(System.in) creates one reader for standard input. We call it input, so input.nextLine() means ask this scanner to read the next line. Scanner is not in java.lang, which is why it needs an import or a fully qualified name.
The examples use try (Scanner input = ...) as a small resource-management wrapper. The code inside its braces uses the scanner, and the wrapper closes it when that block ends, including an early return. These standalone programs own their input stream and then exit. You do not need to master try-with-resources yet; resource ownership is covered in depth later.
Closing a Scanner also closes its underlying closeable source, including System.in here. In a larger application, do not close shared input while another part still needs it. Avoid creating several independent Scanners over System.in because their buffering can interfere. One scanner reading standard input is enough for each of these programs.
next reads a token; nextLine reads the rest of a line
By default, Scanner separates tokens using Java-defined whitespace. next() skips delimiters before the next token and reads that token, so Mina Ben Ali yields Mina first. It does not read the complete name. Token methods are useful when whitespace deliberately separates independent values rather than belonging inside a field.
nextLine() returns the remaining contents of the current line without its line separator, then advances past that separator. It does not first strip all whitespace. After next() reads Mina, the remainder contains the separating space followed by Ben Ali, which is why the brackets below show a leading space.
Choose a read strategy from the field's meaning. Names and free-form notes usually need complete lines. A count and a measurement can be independent tokens when the input contract allows that. Blank lines are meaningful to nextLine, while ordinary token scanning skips whitespace and therefore cannot report each blank line as a separate rejected entry.
Main.java · A token is not the whole line
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
First token: [Mina]
Rest of line: [ Ben Ali]
Numeric methods interpret input text, not Java source literals
nextInt reads an int token and nextDouble reads a double token. Their results are numeric values, not Strings that you still need to cast. Here, 3 and 1.5 can be separated by a space or a line ending because both are token reads. Numeric methods can fail when text has the wrong syntax or cannot fit the requested numeric type.
Scanner starts with a locale-dependent numeric format. useLocale(Locale.ROOT) makes our decimal-point convention explicit for this exercise. The printf calls separately set their display locale. Configuring the input scanner does not automatically configure output formatting, and neither choice makes every possible human number format acceptable.
Input is not Java source code. Do not type suffixes such as 1.5f, underscores such as 1_000, or quotes around a number merely because you saw them in a declaration. Scanner's numeric grammar has its own rules. The simple token examples assume suitable input; the guarded examples and lab below show how to handle rejected values without letting a parse failure crash the program.
Main.java · Read numeric tokens with an explicit locale
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Packages: 3
Weight per package: 1.50
Combined weight: 4.50
Why nextLine can look as if it skipped the name
After nextInt reads 3, it leaves the remainder of that input line to be read. With the supplied input, that remainder is empty immediately before the line ending. nextLine then correctly returns an empty String for that remainder. It did not read the next name line and forget it; it answered a different read request than the programmer intended.
Our input contract puts the number on one line and the complete name on the next. Under that contract, calling nextLine once to consume the unused numeric-line remainder before reading the name is a valid repair. If the input instead put a name on the same line as the number, blindly discarding the remainder would throw useful data away.
Trace the current position after each read. Change the first line to 3 followed by three spaces and observe that the uncorrected name becomes those spaces, not an empty String. For a workflow based on whole lines, another solution is to read every field with nextLine and parse selected lines separately. That makes boundaries explicit instead of mixing token and line reads casually.
Main.java · Observe the leftover line ending
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Quantity: 3
Name: []
Make the one-field-per-line repair explicit
The repaired program below consumes the remainder of the number line on purpose. Its comment explains the input contract, not a mysterious rule that every nextInt must always be followed by nextLine. The next read then obtains the full name, including its interior spaces.
The program still assumes that a valid number and a following name line exist. Removing the name line can cause NoSuchElementException when the program tries to read past the end. Repairing a line-boundary mistake does not automatically validate missing fields or the count's business meaning.
Use the complete-line approach later in this lesson if each attempt must be one whole line. It avoids silently accepting only the first token of a line such as 3 extra. There is no single correct input method for every situation; the important part is making the expected structure and the position of the reader clear.
Main.java · Consume a deliberately unused line remainder
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Quantity: 3
Name: [Mina Ben Ali]
Checking availability is different from consuming input
hasNext asks whether another token exists. hasNextInt asks whether the next token can be read as int under the scanner's configuration. Neither consumes that token. In the guarded example, three fails the int check, so next() consumes it for the rejection message. Rechecking a bad token in a retry loop without consuming anything would inspect the same token forever.
The small if blocks are a preview of the next lesson: if the condition is true, execute the statements inside its braces. An early return ends main, while the resource wrapper still closes the scanner. Read these as explicit guard clauses rather than trying to memorize a complete input framework.
The successful branch prints both the parsed count and whether it is positive. A negative int can pass hasNextInt but fail a domain rule. The token guard also does not reject extra trailing tokens; it reads one token only. Syntax, numeric range, whole-input structure, and application rules are separate checks.
Main.java · Check a token without consuming it
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Not an int token: three
Test parsing versus the quantity rule
With 3, the program prints a parsed quantity of 3 and Positive quantity: true. With -1, it parses successfully but the positive check is false. With no token, it prints No quantity was supplied. None of these paths requires an uncaught input exception.
Read one line, then parse the whole intended field
For one attempt per line, hasNextLine checks that a line is available, nextLine reads it, and strip applies our deliberate boundary-whitespace policy. Integer.parseInt then interprets that whole stripped line as an int. A line such as 3 4 is not one int field, so it is rejected rather than quietly treating 3 as the answer.
parseInt throws NumberFormatException for unsuitable text or a value outside int range. The inner try block attempts that conversion; its catch handles this specific failure with a helpful message. This is a focused preview of exception handling. It does not catch unrelated programming mistakes, and it does not prove that a successfully parsed quantity is within the allowed order range.
Clear the input panel to test end-of-input, enter a blank line to test an empty field, and enter a very large integer to test numeric range. These are different cases. Pressing an empty line is not the same thing as having no next line at all, especially in this runner where the supplied input stream ends after its last character.
Main.java · Parse one complete line intentionally
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Parsed quantity: 3
A parseable number can still be unsuitable
hasNextDouble can accept special floating-point values such as NaN. That means a successful numeric read is not enough for a positive finite measurement. The program explicitly checks Double.isFinite(weight) and weight > 0 after parsing, combining the earlier Math and boolean lessons.
Try 1.5, -1.5, NaN, and Infinity. Only the first satisfies this finite-positive rule. Then try ordinary text: the program should print the nonnumeric-input message instead of attempting nextDouble. A real application may impose additional units, precision, or maximum-value requirements beyond these checks.
Scanner reads and hasNext methods can wait for more data in a normal interactive terminal. In this runner, a complete bounded input stream is already supplied and then closed. No input is not a request for the browser to open a prompt. Treat end-of-input as a normal case that your program can report and stop handling, not as a reason to loop without consuming anything.
Main.java · A parseable double can still be invalid
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Finite positive measurement: false
A retry loop needs progress and an end-of-input path
The lab combines these ideas with a small while loop. while (input.hasNextLine()) means repeat the block while another line is available. Each iteration consumes exactly one nextLine before validating it, so a rejected attempt cannot trap the program on the same input forever.
An if guard prints a specific message for a blank or out-of-range attempt. continue skips the rest of that iteration and checks for another line. A NumberFormatException catch reports non-integer text. When an acceptable quantity is found, the program prints its calculated result and return ends main. If all supplied lines are exhausted first, a final message reports that no valid value was found.
These control-flow constructs are introduced only as much as needed to trace this example; conditions, loops, and exceptions have dedicated lessons later. Follow the input cursor one line at a time and explain which path each line takes. Do not assume that printing a retry message supplies another attempt: in the browser runner you must put all attempts into standard input before Run.
Repair the number-to-name transition
The supplied quantity is on the first line and the learner's full name is on the next. The starter prints an empty name. Repair the read sequence without replacing the name with a fixed literal or discarding part of the actual name.
Main.java · Repair the full-name read
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Reveal the explained repair
nextInt reads the number token but leaves the current line remainder. Because this contract puts the name on the following line, consume that unused remainder once before reading the full name. Do not replace the full-name read with next(), which would accept only Mina. If the data contract changes, revisit the read strategy rather than treating the extra nextLine as universal magic.
Main.java · Repaired full-name read
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Quantity: 3
Name: [Mina Ben Ali]
Independent lab: accept one valid quantity
Read a quantity from 1 through 5, one attempt per line. Reject blank, non-integer, and out-of-range attempts, retry while input remains, and produce a small price calculation only after a valid quantity. This is a local input exercise, not a real order or payment.
- Create one Scanner for System.in and declare final int UNIT_PRICE_CENTS = 1250.
- Print Quantity (1-5), one whole number per line: once, then read each available line using hasNextLine and nextLine.
- Strip the line. If it is empty, print the blank-line message shown below and continue to the next attempt.
- Use Integer.parseInt inside a specific NumberFormatException handler. Reject parsed values below 1 or above 5 with the range message.
- For the first accepted quantity, print the accepted count and quantity times unit price, then end main. Later supplied attempts should not change the accepted result.
- When input ends without an accepted value, print No valid quantity before end of input. Test empty input separately from a blank line.
The starter and solution use these four attempts. The empty third line is intentional:
hello
-1
2
Expected output for that input:
Quantity (1-5), one whole number per line:
Use a whole number from 1 to 5.
Quantity must be between 1 and 5.
Enter a quantity; blank lines are not accepted.
Accepted quantity: 2
Total (cents): 2500
Main.java · Build your quantity reader
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
Show hints without revealing the solution
Consume a complete line at the top of each iteration. Check blank text first, parse with a specific catch, then check the range. A rejected attempt continues; an accepted attempt prints its calculation and returns. Put the EOF message after the loop so it cannot be confused with a successful result.
Reveal the explained lab solution
Main.java · Quantity reader solution
Predict the result, edit Main.java, then run your program.
Standard input · prefilled example
Select Run code to compile and execute this program.
hello fails parsing, -1 parses but fails the allowed range, and the empty line is rejected before parsing. Each rejection consumes a whole attempt. The final 2 is accepted and produces 2500 cents. The range bound keeps this specific integer multiplication small; it does not implement stock, checkout, or persistence. The final EOF message is reachable only when no line was accepted.
Test changes and boundaries
Change standard input rather than rewriting the source for each test. Reset restores the original rejection-and-retry example.
- Enter 1, then separately 5: both boundaries must be accepted, with totals 1250 and 6250.
- Enter 0 and 6 followed by 3: both invalid values get range messages before quantity 3 is accepted.
- Enter 3 4 or 3.5 on a line: neither is a whole int field; each should get the parsing message.
- Clear the input panel: the prompt and EOF message should appear without a crash. Supply one blank line instead: also expect the blank-line message.
- Supply an integer larger than int range and then 2: report the parsing failure and recover. Supply 2 then 5: accept only the first valid quantity and stop.
Common mistakes and how to diagnose them
First identify whether input was exhausted, a token was invalid, a line boundary was misunderstood, or a parsed value violated a rule. The same extra read or broad exception handler cannot safely solve every case.
InputMismatchException
A token did not match the requested numeric type or its range. Check the input text and scanner locale. A failed nextInt does not consume the bad token; a retry must consume or replace that attempt rather than reread it endlessly.
NoSuchElementException
The program attempted to read beyond the supplied input. Count the expected fields and inspect hasNext or hasNextLine guards. In this runner, provide the complete input before Run; typing into an output panel cannot supply a missing line.
An empty name after nextInt
nextLine may be reading the remainder of the number's current line. Trace the cursor and apply the actual input contract. Consume a remainder only when it is deliberately unused, or consistently read whole lines and parse selected fields.
The retry message repeats or never reaches new data
Checking with hasNextInt does not consume a rejected token. Ensure each attempt makes progress and that EOF exits the loop. Avoid catching a parse error and immediately calling the same read on the same untouched token.
A negative or non-finite value was accepted
Parsing only establishes a representation. Apply the required range and finite-value rules afterward. A successfully read int can be negative, and a double can be NaN or infinite.
Input works on one machine but not another
Check numeric locale, decimal separators, token versus line boundaries, and whether the source is interactive or finite. State the intended input grammar and configure the scanner deliberately instead of guessing from a successful local example.
Frequently asked questions
Where do I type replies in this lesson?
Use the standard-input box before selecting Run. It contains the complete input stream. The output panel is not interactive, and the stream ends after the supplied text. The prefilled examples can be run unchanged.
Does hasNextInt read and remove the number?
No. It checks whether the next token can be read as int. nextInt performs the actual read. A rejected token must be consumed or handled deliberately if the program will retry.
Should I always add nextLine after nextInt?
No. It is appropriate when the remainder of that numeric line is unused and the next field belongs to a new line. If useful text is on the same line, blindly discarding the remainder loses it. Choose a consistent input contract.
Why does the lab read lines and then parse instead of using nextInt?
Each attempt is required to occupy a complete line, and blank attempts need their own message. Token methods skip whitespace and can accept a numeric prefix token while leaving extra tokens. Whole-line parsing makes these boundaries explicit.
Are these programs ready to collect real personal data or orders?
No. They demonstrate local input and validation with invented data. They do not implement authentication, storage, payments, or server-side authorization. Do not enter secrets into the lesson runner.
Read, interpret, validate, and handle the end
Scanner reads a stream according to token or line rules. Checks do not consume input, parsing does not establish business validity, and prompting does not create another input value. A reliable retry path consumes attempts and stops at EOF.
Before moving on, trace the cursor through the quantity/name example and explain why the lab rejects a blank line differently from missing input. Next is Java If, Else If, and Else, where those small guard blocks become a full control-flow topic.
Can you follow what the input reader consumes?
Answer all six questions and read the reasoning. Results are temporary on this page and do not save course progress.
References and related learning
The input scenarios, explanations, and exercises are original SovranCode material. These official references support the language and API rules.
- Java 21 Scanner API: tokens, lines, locale, and input failures
- Java 21 Integer API: parseInt
- Java 21 System API: standard input
- Java 21 specification: while, continue, and try statements
Review full text values · Review boolean guards · Java course roadmap.
Last updated: