Java • Problem-Solving Patterns

Input Validation — Validate assumptions and handle invalid input formats (as specified)

Learn to write robust Java programs that gracefully handle unexpected or malformed user input.

Java programming emblem with a coffee cup, code braces, and terminal
Inside this lesson 10 sections 5 questions 4 figures

SECTION 1

Historical Context & Motivation

Every program you have ever used relies on data coming in from the outside world — keyboard input, file contents, network messages, or sensor readings. When that data arrives in an unexpected format, a program can crash, produce wrong results, or even expose security vulnerabilities. Input validation is the practice of checking every piece of incoming data before your program acts on it. The concept has been central to software engineering since the earliest days of computing, and its importance has only grown as software has become more interconnected.

1960s • Early Mainframe Era

Programmers using punch cards discovered that a single misplaced character could crash an entire batch job. Early defensive programming practices emerged to check card data before processing.

1988 • The Morris Worm

One of the first internet worms exploited a lack of input validation in Unix programs. It demonstrated that unchecked input could be weaponized to compromise thousands of machines.

1995 • Java's Exception Model

Java was released with built-in exception handling (try-catch), giving developers a structured way to detect and respond to invalid input at runtime.

2004 • OWASP Top 10 Published

The Open Web Application Security Project listed 'Unvalidated Input' as a top web vulnerability, making input validation a mainstream security requirement for all developers.

2020s • Modern Frameworks & AP CS A

Today, input validation is a core problem-solving pattern taught in AP Computer Science and used in every professional Java application, from Android apps to cloud services.

The central question this lesson addresses is straightforward but powerful: How do you write Java code that never blindly trusts incoming data? By the end of this lesson, you will know how to validate assumptions about input, handle invalid formats gracefully, and build programs that are both correct and resilient.

SECTION 2

Core Principles of Input Validation

Input validation follows a few foundational ideas that apply whether you are reading integers from the console, parsing strings from a file, or processing data from a web form. These principles form a mental checklist you can use every time your program expects data from an external source.

1

Never Trust External Data

Any data entering your program — from a user, a file, or the network — should be treated as potentially invalid until your code has verified it. This is the golden rule of defensive programming.
2

Validate Early, Fail Fast

Check input as close to the entry point as possible. If data is bad, reject it immediately rather than letting it travel deep into your logic where errors become harder to trace.
3

Provide Clear Feedback

When input is invalid, tell the user exactly what went wrong and what format is expected. A message like 'Enter a positive integer' is far better than 'Error.'
4

Use Loops for Re-prompting

In interactive programs, wrap input collection in a loop that keeps asking until valid data is received. This pattern ensures your program doesn't crash or silently accept bad data.
5

Handle Exceptions Gracefully

Java's try-catch mechanism lets you intercept runtime errors (like InputMismatchException or NumberFormatException) and recover instead of crashing.
✦

KEY TAKEAWAY

Think of input validation like a bouncer at a concert venue. The bouncer checks every ticket before letting someone through the door. If the ticket is fake or expired, the bouncer doesn't let the person in — and certainly doesn't let them backstage. Your validation code is the bouncer: it stands at the entrance to your program and only lets well-formed, expected data pass through.

SECTION 3

Visual Explanation — The Validation Pipeline

Input Validation PipelineUser Input"abc", "42", ""Type CheckIs it the rightdata type?Range CheckIs the valuewithin bounds?Format CheckDoes it matchexpected pattern?✓ VALIDProcess the data✗ INVALID — Error Handling ZoneDisplay error message → Re-prompt user or throw exceptionRe-prompt LoopFailFailFailData must pass every gate before reaching your core logic.
The validation pipeline shows how raw user input flows through three gates — type check, range check, and format check. If input fails at any gate, it is rejected and the user is re-prompted through the loop on the left.

In the diagram above, notice that data must pass through every gate before it reaches your core program logic. The type check ensures the input is the correct data type — for instance, verifying that a supposed integer isn't actually a string of letters. The range check verifies the value falls within acceptable bounds, such as an age between 0 and 150. The format check confirms the input matches a required pattern, like a date in MM/DD/YYYY format. If any check fails, the dashed yellow re-prompt loop brings the user back to the start.

SECTION 4

How Input Validation Works in Java

Java provides several built-in tools for input validation. Understanding when and how to use each tool is essential for writing robust programs. The three primary mechanisms are conditional checks (if statements), Scanner's hasNext methods, and try-catch exception handling.

Technique 1: Conditional Checks (if / else)

The simplest form of validation uses an if statement to test a condition. For example, after reading an integer, you can check whether it falls within an expected range. If the condition fails, you print an error message and either re-prompt or exit. This approach works best when you have already successfully read the data and just need to verify its value.

Technique 2: Scanner's hasNext Methods

Java's Scanner class offers methods like hasNextInt(), hasNextDouble(), and hasNextLine() that let you peek at the next token without consuming it. These are powerful because they let you test the type before you try to read, avoiding exceptions entirely. A common pattern is to loop with while (!scanner.hasNextInt()), consuming and discarding the invalid token inside the loop body.

Technique 3: Try-Catch Exception Handling

When using methods like Integer.parseInt() or Double.parseDouble(), invalid input causes a NumberFormatException. You can wrap these calls in a try block and catch the exception in a catch block. This prevents your program from crashing and lets you display a helpful message. Combining try-catch with a while loop creates a robust input routine that keeps asking until valid data arrives.

⚠

Common Exceptions to Know

• InputMismatchException — thrown by Scanner when input doesn't match the expected type. • NumberFormatException — thrown by Integer.parseInt() or Double.parseDouble() when the string cannot be converted. • StringIndexOutOfBoundsException — thrown when accessing a character index that doesn't exist in a string.

SECTION 5

Common Validation Patterns in Java

Now that you understand the three core mechanisms, let's look at specific validation patterns you'll encounter in typical Java assignments and projects. Each pattern below addresses a different kind of assumption you might need to verify.

Five Common Validation Patterns1. Integer in Rangeif (num >= min && num <= max) { // valid} else { // invalid — re-prompt2. Non-Empty Stringif (str != null && !str.trim().isEmpty()) { // valid}3. Try-Catch Parsetry { int n = Integer.parseInt(s);} catch (NumberFormatException e) { System.out.println("Invalid");}4. Scanner hasNext Loopwhile (!scan.hasNextInt()) { System.out.println("Try again"); scan.next(); // discard bad input}int val = scan.nextInt();5. Menu Choice Validationdo { System.out.print("Choose 1-4: "); choice = scan.nextInt();} while (choice < 1 || choice > 4);Each pattern targets a specific kind of invalid input.
These five code snippets represent the most common validation patterns you will use in Java. Pattern 1 handles range checking, Pattern 2 handles null/empty strings, Pattern 3 uses try-catch, Pattern 4 uses hasNext with a while loop, and Pattern 5 demonstrates do-while menu validation.

When choosing a pattern, think about what could go wrong. If the user might type letters when you expect a number, use Pattern 3 or Pattern 4. If the user will definitely enter a number but it might be out of range, Pattern 1 or Pattern 5 is sufficient. If you are reading a name or other text, Pattern 2 ensures you don't process a blank entry. In practice, you'll often combine multiple patterns — for example, first catching a NumberFormatException and then checking the range of the parsed value.

SECTION 6

Worked Example — Age Validator Program

Let's build a complete program that asks the user for their age and keeps re-prompting until a valid integer between 0 and 150 is entered. This example combines the Scanner hasNext loop with a range check.

Building an Age Validator Step by Step

  1. 1

    Step 1 — Set Up the Scanner and Variables

    Import java.util.Scanner and create a Scanner object to read from System.in. Declare an int age variable and a boolean valid flag initialized to false.
    Scanner scan = new Scanner(System.in); int age = 0; boolean valid = false;
  2. 2

    Step 2 — Create the Validation Loop

    Use a while (!valid) loop that continues asking for input until the valid flag becomes true. Inside the loop, print a prompt asking the user to enter their age.
    while (!valid) { System.out.print("Enter your age (0-150): "); ... }
  3. 3

    Step 3 — Check the Type with hasNextInt()

    Inside the loop, check if the next token is an integer using scan.hasNextInt(). If it is not, print "That's not a number. Try again." and call scan.next() to discard the invalid token. If it is an integer, read it with scan.nextInt().
    if (!scan.hasNextInt()) { System.out.println("Not a number."); scan.next(); } else { age = scan.nextInt(); }
  4. 4

    Step 4 — Check the Range

    After successfully reading the integer, check whether it falls between 0 and 150 inclusive. If it does, set valid = true to exit the loop. If it doesn't, print "Age must be between 0 and 150." and the loop repeats.
    if (age >= 0 && age <= 150) { valid = true; } else { System.out.println("Age must be 0-150."); }
  5. 5

    Step 5 — Use the Validated Input

    After the loop exits, you can safely use age in your program, confident it is a valid integer within the expected range. Print a confirmation message and close the Scanner.
    System.out.println("Your age is: " + age); scan.close();
💡

Why call scan.next() on invalid input?

When hasNextInt() returns false, the invalid token is still sitting in the Scanner's buffer. If you don't consume it with scan.next(), the loop will check the same bad token forever, creating an infinite loop. Always discard the bad input before re-prompting!

SECTION 7

Strengths & Limitations of Each Approach

Each validation technique has trade-offs. The table below compares the three main approaches so you can choose the right tool for the job.

TechniqueStrengthsLimitations
Conditional Checks (if/else)Simple to write and understand. No exception overhead. Good for range and logic validation after data is already parsed.Cannot catch type mismatches at the parsing stage. Only works if the data is already in the correct type.
Scanner hasNext MethodsPrevents exceptions before they happen. Clean loop pattern. Works well for console-based programs.Only available with Scanner. Does not work when parsing strings directly. Requires remembering to discard invalid tokens.
Try-Catch Exception HandlingWorks with any parsing method (parseInt, parseDouble, etc.). Catches unexpected errors. Can handle multiple exception types.Slightly more complex syntax. Using exceptions for normal flow control is considered less efficient. Can mask other bugs if the catch block is too broad.

Comparison of the three main Java input validation techniques

✦

KEY TAKEAWAY

Think of these techniques as different tools in a toolbox. A screwdriver (if/else) is great for tightening screws but won't hammer a nail. A hammer (try-catch) is powerful but overkill for a screw. A measuring tape (hasNext) helps you check before you even pick up a tool. Good programmers choose the right tool for each validation task, and often combine tools for maximum safety.

SECTION 8

Connection to Advanced Concepts

The input validation skills you learn here are the foundation for much more advanced programming concepts. As you move toward AP Computer Science and beyond, you'll encounter validation in increasingly sophisticated contexts.

What You Learn NowWhere It Leads
Checking if input is an integerType-safe generics and compile-time type checking in advanced Java
Try-catch for NumberFormatExceptionCustom exception classes, checked vs. unchecked exceptions, exception hierarchies
Range checking with if statementsPreconditions and postconditions in Design by Contract (used in professional software)
Validating user input from consoleSanitizing web form input to prevent SQL injection and cross-site scripting (XSS) attacks
Re-prompting with while loopsEvent-driven validation in GUI applications with JavaFX or Android

How basic validation concepts connect to advanced topics

One particularly important advanced concept is regular expressions (regex), which let you define complex patterns for valid input — like email addresses, phone numbers, or dates. Java's String.matches() method accepts a regex pattern and returns true or false. While regex is beyond the scope of this lesson, the mindset is the same: define what valid input looks like, then reject anything that doesn't match. The defensive programming mindset you develop now will serve you throughout your entire programming career.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

A program uses Scanner.nextInt() to read a number, but the user types "hello". What happens if there is no validation code? Explain why this is a problem and name the specific exception that Java throws.
Show answer
Java throws an InputMismatchException because "hello" cannot be parsed as an integer. Without validation, this exception is unhandled and the program crashes immediately, printing an error stack trace. This is a problem because it gives the user no chance to correct their mistake and provides no helpful feedback. Proper validation would either use hasNextInt() to check before reading or wrap the call in a try-catch block to recover gracefully.

Question 2: BASIC CALCULATION

Write a short Java code snippet that uses Integer.parseInt() inside a try-catch block to convert a String variable called userInput to an integer. If the conversion fails, print "Please enter a valid integer." What exception type should the catch block handle?
Show answer
The catch block should handle NumberFormatException. The code would be: try { int num = Integer.parseInt(userInput); System.out.println("You entered: " + num); } catch (NumberFormatException e) { System.out.println("Please enter a valid integer."); } The try block attempts the conversion, and if userInput contains non-numeric characters like "abc" or "12.5", parseInt throws a NumberFormatException which the catch block intercepts, preventing a crash and displaying a user-friendly message.

Question 3: INTERMEDIATE

Write a method called getValidGrade(Scanner scan) that asks the user for a test score between 0 and 100 inclusive. The method should handle both non-integer input and out-of-range values, re-prompting until a valid score is entered, then return the validated integer.
Show answer
The method combines the hasNextInt loop with a range check. Here is the approach: public static int getValidGrade(Scanner scan) { int grade = -1; boolean valid = false; while (!valid) { System.out.print("Enter grade (0-100): "); if (!scan.hasNextInt()) { System.out.println("That is not a number."); scan.next(); } else { grade = scan.nextInt(); if (grade >= 0 && grade <= 100) { valid = true; } else { System.out.println("Grade must be between 0 and 100."); } } } return grade; } The outer while loop continues until valid becomes true. First, hasNextInt() checks the type. If the type is correct, a nested if checks the range. The method returns only after both checks pass.

Question 4: APPLIED

You are building a pizza ordering program. The user must enter the number of pizzas (a positive integer) and a size code ("S", "M", or "L"). Describe the validation strategy you would use for each input. What specific checks are needed, and what errors could occur if you skip validation?
Show answer
For the number of pizzas, you need two validations: first, verify the input is an integer (using hasNextInt or try-catch with parseInt), and second, verify it is positive (greater than 0). If you skip validation, a user could enter "zero" or a negative number, leading to nonsensical orders or program errors. For the size code, you need to read a String and check that it equals "S", "M", or "L" using the equalsIgnoreCase() method (to handle uppercase and lowercase). Without this check, a user could type "XL" or "pizza" and the program would either crash when trying to calculate the price or silently produce an incorrect order. Both inputs should be wrapped in re-prompting loops to ensure the program collects valid data before proceeding.

Question 5: CRITICAL THINKING

Consider two approaches to validating integer input: (A) using scanner.hasNextInt() before reading, and (B) reading a String first, then using Integer.parseInt() inside a try-catch. Under what circumstances would approach B be better than approach A? Can you think of a scenario where neither approach alone is sufficient?
Show answer
Approach B is better when you are not using a Scanner at all — for example, when reading data from a file line by line, receiving input from a GUI text field, or processing command-line arguments stored in the String[] args array. In all these cases, hasNextInt() is unavailable because there is no Scanner, so try-catch with parseInt is the natural choice. A scenario where neither approach alone is sufficient: suppose the input must be an even integer between 10 and 50. Both approaches handle the type check (is it an integer?), but neither automatically checks whether the number is even or within range. You would need to combine the type validation from either approach with additional conditional checks for range and the even/odd constraint (using the modulus operator num % 2 == 0). This illustrates that real-world validation usually requires layering multiple checks together.

SUMMARY

Lesson Summary

Summary

Input validation is the practice of checking all external data before your program uses it. You learned three core techniques: conditional checks with if/else statements for range and logic validation, Scanner's hasNext methods to peek at input before reading it, and try-catch exception handling to recover gracefully from parsing errors like NumberFormatException and InputMismatchException.

The five key principles are: never trust external data, validate early and fail fast, provide clear error feedback, use loops for re-prompting, and handle exceptions gracefully. Every piece of data entering your program — whether from the keyboard, a file, or the network — should pass through a validation pipeline that checks its type, range, and format before your core logic processes it. Building this defensive programming habit now prepares you for secure, professional software development.

Varsity Tutors • Java • Input Validation — Validate assumptions and handle invalid input formats (as specified)