Input Validation - Java

  1. Which approach most accurately enforces the specified line-oriented input format?
    Answer: Call nextLine(), apply trim(), and pass the resulting string to Integer.parseInt(). When dealing with line-oriented input validation in Java, the key question is: does your approach actually read and validate a complete line at once? The specification requires that each line contain exactly one integer and nothing else — meaning extra trailing text like "42 abc" must be rejected. Option B correctly enforces this by calling nextLine() to consume the entire line, applying trim() to strip surrounding whitespace, and passing the clean string directly to Integer.parseInt(). If the trimmed string contains anything beyond a valid integer (extra tokens, letters, symbols), parseInt() throws a NumberFormatException, which you catch to reject the input. This approach treats the line as a whole unit, exactly as the specification demands. Option A is the most tempting trap. hasNextInt() followed by nextInt() only confirms that the next token is an integer — it doesn't check what follows it on the same line. Calling nextLine() afterward discards the remainder, but the integer was already accepted, meaning "42 abc" would pass validation incorrectly. Option C uses next(), which reads only one whitespace-delimited token, not an entire line. It similarly has no mechanism to detect or reject extra content on the same line, so "42 abc" would again slip through. Option D calls nextInt() directly and uses skip(".*") to consume remaining input, but like A and C, it accepts the integer before checking whether the line contains anything else — and skip with a greedy pattern can behave unpredictably across line boundaries. Study tip: Whenever a problem specifies line-oriented validation, default to nextLine() as your input method — it's the only Scanner call that treats an entire line as a single unit.
  2. Which condition safely enforces all of these requirements?
    Answer: password != null && password.length() >= 8 && password.length() <= 20 && password.equals(password.strip()) When working with conditional validation in Java, the order of operations matters enormously — especially when null checks are involved. Before calling any method on an object, you must verify it isn't null, or you risk a NullPointerException at runtime. Option B gets this right by placing password != null first, then checking password.length() within the 8–20 range, and finally confirming password.equals(password.strip()) to ensure no leading or trailing Unicode whitespace exists. Because Java uses short-circuit evaluation with &&, if password is null, the entire expression stops immediately — the length and strip checks never execute. This is the safe, correct pattern. Option A fails for a subtle but critical reason: it calls password.length() before checking password != null. If a null value is passed in, Java throws a NullPointerException before the null check is ever reached. The null guard must come first. Option C is deceptive because it calls password.strip() to check the length, which silently accepts passwords that have whitespace padding the character count into range. The passage explicitly states the program must reject invalid input, not quietly modify or reinterpret it. Stripping before measuring changes the length being validated. Option D replaces && with || after the null check, which breaks the entire logic. Using || means the expression can evaluate to true even when individual conditions fail — for example, a null password would satisfy the first operand alone. The key takeaway: always place your null check at the very start of a compound && condition, and watch for options that silently transform data before validating it — that's a common trap in Java validation questions.
  3. After parsing succeeds, which condition is necessary and sufficient to accept the value?
    Answer: Double.isFinite(value) && value >= 0.0 When working with floating-point validation in Java, you need to understand the three distinct categories of double values: normal finite numbers, infinities (Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY), and NaN ("Not a Number"). The specification here demands both finite and nonnegative, so your condition must eliminate all three problem cases: negative values, infinities, and NaN. Double.isFinite(value) returns true only when a value is neither infinite nor NaN — it rules out both bad cases in one call. Combined with value >= 0.0, option A precisely captures "finite and nonnegative," making it both necessary (you need both conditions) and sufficient (together they guarantee validity). Option B (!Double.isNaN(value) && value >= 0.0) is a common trap. It correctly excludes NaN but fails to reject infinities — Double.POSITIVE_INFINITY >= 0.0 evaluates to true, so an infinite value would pass this check even though the spec forbids it. Option C uses || instead of &&, meaning a value only needs to satisfy one of the two conditions. This would accept negative infinities (which are finite... wait — no, it would accept negative finite numbers because isFinite is true) and generally produces far too permissive a gate. The logical connector must be && for a conjunctive requirement. Option D is a subtle but critical mistake: **you cannot compare to Double.NaN using !=**. By IEEE 754 specification, NaN is not equal to anything, including itself — so value != Double.NaN is always true, making the NaN check completely useless. Remember: whenever you need to validate floating-point input in Java, reach for Double.isFinite() rather than separate NaN and infinity checks — it handles both in one reliable call.
  4. Which validation expression implements the requirement exactly?
    Answer: Pattern.compile("[A-Z]{2}[0-9]{4}").matcher(code).matches() When validating input with Java's regex engine, the critical distinction is between finding a pattern somewhere in a string versus matching the entire string against a pattern. This question tests exactly that difference. The requirement says the entire input must consist of two uppercase letters followed by four digits — nothing more, nothing less. Option A uses .matches(), which implicitly anchors the pattern to the full string (equivalent to wrapping your regex in ^...$). So [A-Z]{2}[0-9]{4} with .matches() accepts only strings like "AB1234" and rejects anything with extra characters before, after, or embedded. That's precisely the behavior you need, making A the correct answer. Option B is the classic trap here. Using .find() instead of .matches() searches for the pattern anywhere within the input. A string like "!!AB1234!!" would pass validation because the pattern is found inside it, violating the "no surrounding characters" rule. Option C applies Pattern.CASE_INSENSITIVE, which means lowercase letters like "ab1234" would now pass. The requirement explicitly restricts input to uppercase ASCII letters, so this flag directly contradicts the spec. Option D uses [0-9]{4,}, the quantifier for four or more digits. This would accept "AB12345" or "AB123456789", breaking the exactly-four-digits constraint. A useful rule of thumb: **always use .matches() when the spec says "the entire input must be..."** and reserve .find() for searching within larger text. Mixing these two up is one of the most common regex bugs in Java, and exams love to test it.
  5. Which implementation correctly distinguishes invalid text from a valid false value?
    Answer: if (s == null || !(s.equalsIgnoreCase("true") || s.equalsIgnoreCase("false"))) return Result.invalid(); return Result.valid(Boolean.parseBoolean(s)); When validating configuration strings, you need to think carefully about two things: case sensitivity and what happens with unexpected input. The goal here is to accept only "true" or "false" in any case, reject everything else (including empty strings), and then safely convert to a primitive boolean. Option C is correct because it handles all three concerns cleanly. It first guards against null, then uses equalsIgnoreCase to check whether the string is either "true" or "false" — rejecting anything else before calling Boolean.parseBoolean. This means invalid input never slips through. Option A is wrong because Boolean.parseBoolean never throws an exception and never returns null — it simply returns false for any string that isn't "true" (case-insensitive). So "banana", "", and "false" all return false, making it impossible to distinguish invalid input from a legitimate false value. Option B is wrong because the comparison uses equals (case-sensitive), not equalsIgnoreCase. This means "True", "FALSE", or "True" would all be treated as invalid, violating the requirement that any mixture of uppercase and lowercase must be accepted. Option D is wrong because Boolean.valueOf(s) never returns null — it returns a Boolean object, either Boolean.TRUE or Boolean.FALSE. For any unrecognized string it returns Boolean.FALSE, so the null check is always false and invalid input passes through undetected. As a study tip: whenever you see Boolean.parseBoolean or Boolean.valueOf, remember that neither throws exceptions nor returns null for bad input — they silently default to false. Always validate first if you need to distinguish "false" from "invalid."
  6. Which method returns true exactly for inputs satisfying both the lexical and range requirements?
    Answer: if (s == null || !s.matches("0|[1-9][0-9]{0,9}")) return false; try { Integer.parseInt(s); return true; } catch (NumberFormatException e) { return false; } When validating user input against both a format rule and a value rule, you need to verify that both constraints are satisfied independently — neither one alone is sufficient. The passage defines a canonical nonnegative int as something that (1) matches the pattern 0 or a 1–10 digit string starting with 1–9, and (2) fits within Java's int range. Option A handles both correctly: it first rejects anything that fails the regex 0|[1-9][0-9]{0,9}, which enforces no leading zeros and at most 10 digits. Then it attempts Integer.parseInt(s) inside a try-catch — necessary because a 10-digit number like 2147483648 passes the regex but overflows int. If parsing throws NumberFormatException, it returns false. This two-gate approach catches every edge case. Option B skips the lexical check entirely, so strings like "007" (leading zeros) would pass since Integer.parseInt("007") returns 7, which is >= 0. It only enforces range, not canonical format. Option C passes the regex check correctly but then calls Long.parseLong(s) and casts to int — this is broken because casting an overflowing long to int in Java doesn't throw an exception, it silently wraps around. For example, 2147483648L cast to int gives -2147483648, and (int) v >= 0 would return false instead of catching it properly. Option D uses the regex [0-9]{1,10}, which allows leading zeros (e.g., "01") — violating the canonical format rule even though parseInt would otherwise succeed. Study tip: When you see a validation problem, always ask yourself: does this solution check both structure and range? A regex alone can't catch overflow, and parseInt alone can't catch format violations like leading zeros.
  7. Which code correctly validates and separates the input?
    Answer: String[] p = line.split("=", 2); boolean valid = p.length == 2 && !p[0].isEmpty() && !p[1].isEmpty(); When working with string parsing in Java, the key question is always: does your approach handle edge cases that the problem explicitly defines? Here, the rule is that the first equals sign separates key from value, meaning the value itself may contain = characters. The right tool for this is split(String regex, int limit) with a limit of 2. Passing 2 tells Java to split into at most two parts, stopping after the first match. So token=a=b correctly becomes ["token", "a=b"]. After splitting, you validate that both parts exist (p.length == 2) and neither is empty. This is exactly what D does, making it the correct answer. A is tempting but fatally flawed: split("=") with no limit splits on every =. So token=a=b produces three parts, p.length == 2 fails, and valid input gets rejected. This is the classic trap of forgetting the limit parameter. B uses indexOf and lastIndexOf to ensure exactly one = exists — which actively rejects valid input like token=a=b since indexOf and lastIndexOf return different positions. The logic is backwards relative to the problem's rules. C checks only that = exists somewhere, which doesn't verify a nonempty key or value. A line like =value or key= would pass incorrectly. Validation here is far too weak. The study tip: whenever a parsing problem says "the first occurrence of X is the separator," reach for split(regex, 2) — the limit parameter is what makes this work correctly.
  8. Which sequence of operations most reliably enforces the specification?
    Answer: Parse inside a try block, reject parse failure, check both bounds, and only then allocate new Record[count]. When validating external input before allocating resources, the golden rule is: validate completely before committing any resources. Allocating memory based on untrusted data — then checking whether that allocation was appropriate — inverts the correct order of operations and can waste or corrupt resources. Option B gets this right. By parsing inside a try block, you catch NumberFormatException if the input isn't a valid integer at all. Then you check both bounds (count >= 0 and count <= 10000) before ever calling new Record[count]. Only when all validation passes does allocation happen. This is the canonical "validate, then act" pattern. Option A allocates the array before fully validating — if count is negative, you've already triggered a NegativeArraySizeException, and if it's enormous, you've wasted memory before rejecting it. Validation after allocation is too late. Option C uses Math.abs(count) to silently convert negative values into positive ones, which masks invalid input rather than rejecting it. The specification says invalid values must be rejected — quietly laundering them is a bug disguised as a fix. Relying on allocation failure as your error signal is also fragile. Option D catches NegativeArraySizeException as a control-flow mechanism, which is an antipattern — exceptions should signal exceptional conditions, not substitute for an if statement. Truncating out-of-range values also violates the spec's requirement to reject them. Study tip: On questions about input validation, always look for the answer that checks all conditions before performing any side effects (allocation, I/O, state changes). If an option allocates first and validates second, it's almost certainly wrong.
  9. Which expression correctly determines whether line has exactly four fields under this specification?
    Answer: line.split(",", -1).length == 4 When working with String.split() in Java, the key detail to understand is how the limit parameter controls trailing empty string behavior — and this question is entirely about that behavior. The specification says empty fields, including the final field, are permitted. This means a line like "a,b,," must produce four fields: ["a", "b", "", ""]. Whether your split correctly captures that trailing empty field depends entirely on which overload you use. Option C, line.split(",", -1), is correct. A negative limit tells Java to apply the pattern as many times as possible without discarding trailing empty strings. So "a,b,," yields length 4, and "a,b,c,d" also yields length 4 — exactly what the spec requires. Option A, line.split(","), uses the no-argument overload, which is equivalent to a limit of 0. Both silently discard trailing empty strings, meaning "a,b,," would return length 2 — a four-field record would incorrectly fail validation. Option B, line.split(",", 4), uses a positive limit, which caps the number of tokens at 4. This means if the input has five or more fields (like "a,b,c,d,e"), split stops early and the last token swallows the remainder — making an invalid record appear valid. It won't correctly reject overly long lines. Option D, line.split(",", 0), is explicitly documented as equivalent to the no-argument form, so it shares the same trailing-empty-string problem as A. Study tip: Memorize this rule — negative limit preserves trailing empties, zero/no-argument drops them, positive limit caps token count. Questions about parsing delimited records almost always hinge on trailing empty fields.
  10. Which formatter and parse operation best enforce this requirement?
    Answer: DateTimeFormatter f = DateTimeFormatter.ofPattern("uuuu-MM-dd").withResolverStyle(ResolverStyle.STRICT); LocalDate.parse(text, f); When working with date parsing in Java, you need to think about two separate concerns: the pattern letters used and the resolver style applied. Both must be correct to enforce strict calendar validation. Java's DateTimeFormatter supports two similar-looking pattern letters for year: yyyy (era-based year) and uuuu (proleptic calendar year). For strict validation, uuuu is required because ResolverStyle.STRICT demands it — using yyyy with STRICT actually throws a DateTimeParseException due to a missing era field. This makes option C the correct choice: it pairs uuuu-MM-dd with ResolverStyle.STRICT, which rejects any date that doesn't correspond to a real calendar day, like February 30th or April 31st. Option A is tempting because DateTimeFormatter.ofPattern("uuuu-MM-dd") looks reasonable, but the default resolver style is SMART, not STRICT. SMART mode adjusts certain invalid values rather than rejecting them outright, so it won't reliably catch all invalid dates. Option B explicitly sets ResolverStyle.LENIENT, which is the opposite of what you want — it actively adjusts out-of-range values (e.g., February 30th becomes March 2nd), completely defeating the requirement to reject invalid dates. Option D uses ResolverStyle.STRICT but pairs it with yyyy instead of uuuu. As mentioned, this combination fails at runtime because STRICT mode requires a proleptic year field (uuuu) when no era is provided. A useful rule of thumb: whenever you see ResolverStyle.STRICT on the exam, check that the pattern uses uuuu, not yyyy. The two always travel together for strict date validation.

Start this quiz