WHAT YOU WILL MAKE
Make safe backpack administrator SafeInventory
The user inputs "a lot" and the program does not have to end immediately. You'll read exception clues, catch recoverable failures, check all conditions before writing to inventory, and provide actionable prompts. Prerequisites: methods, conditional judgments, Map and string conversion. Today, when the player inputs a lot of diamonds, the program will not explode on the spot like a creeper.
Before you start: It is recommended to complete Lessons 25–27 first
- Exception typeExplain which type of operation failed
- MessageGive specific input clues
- Source file line numberLocate your own code
01 / 15
Before starting: predict first, then let the program answer
This chapter uses JDK 21 and does not require the preview function. The story is borrowed from the block world, and the example runs on the ordinary Java console; if the values and rules are course models, they will be clearly stated.
Each common example is a complete independent file, saved according to the file name marked on the box. Place each example in a different folder to avoid duplicate names of auxiliary classes. When the complete project is divided into sections, they are connected sequentially in the same file.
Terminal command: replace the Chinese placeholder with the actual file name and class name
javac -encoding UTF-8 ExampleFile.java
java ExampleClass- Prediction: Write the expected output first, or draw out the changes in references and data.
- Verification: Check line by line after running, and then only change one condition.
- Explanation: Explain whether the results come from Java rules, course contracts, or input data.
02 / 15
Exception reporting failed operation
An exception is not a notification that the programmer has been deducted points, but a fault report sent when it is discovered that the operation cannot be completed normally during runtime.
The stack trace lists the method call path. First look at the exception type and message, and then find the first line pointing to your source file.
- Exception typeExplain which type of operation failed
- MessageGive specific input clues
- Source file line numberLocate your own code
BadNumber.java · Intentional error example
public class BadNumber {
public static void main(String[] args) {
int amount = Integer.parseInt("Many");
System.out.println(amount);
}
}03 / 15
try catch handles recoverable errors
Converting string to integer may fail. If the user can re-enter, catch the NumberFormatException and return an understandable result.
- tryOnly put operations that may fail
- catchHandling recoverable errors
- Return -1 on failureNot to be confused with legal positive numbers
L28Example02.java · Complete independent example
public class L28Example02 {
static int parseAmount(String text) {
if (text == null) return -1;
try {
int amount = Integer.parseInt(text.strip());
return amount > 0 ? amount : -1;
} catch (NumberFormatException error) { return -1; }
}
public static void main(String[] args) {
System.out.println(parseAmount("12"));
System.out.println(parseAmount("Many"));
}
}Output
12
-104 / 15
Capture specific exceptions
Although catching Exception saves words, it may mislead program errors into user input problems. Prioritize capturing specific types that you can handle explicitly.
- Specific exceptionNumberFormatException first
- Parent class exceptionIllegalArgumentException follows
- UnrecoverableKeep spreading, don’t pretend to be successful
L28Example03.java · Complete independent example
public class L28Example03 {
public static void main(String[] args) {
for (String text : new String[]{"Many", "80"}) {
try {
int amount = Integer.parseInt(text);
if (amount < 1 || amount > 64)
throw new IllegalArgumentException(
"The single quantity must be within 1 to 64 between: " + amount);
System.out.println("The quantity is legal=" + amount);
} catch (NumberFormatException error) {
System.out.println("Quantity must be an integer: " + text);
} catch (IllegalArgumentException error) {
System.out.println(error.getMessage());
}
}
}
}Output
Quantity must be an integer: Many
The single quantity must be within 1 to 64 between: 8005 / 15
Ordinary verification does not need to throw exceptions
It is a common business situation for players to enter an empty name, and verification rules can be directly expressed using if. Exceptions are used for operations that cannot be completed normally; the choice depends on the calling contract, rather than treating exceptions as ordinary branching loops.
- Common verificationFor empty names, use if first
- Clear the contractWhat is the legal input?
- No side effectsOperate only after passing inspection
L28Example04.java · Complete independent example
public class L28Example04 {
static boolean validName(String name) { return name != null && !name.isBlank(); }
public static void main(String[] args) {
System.out.println(validName(" "));
System.out.println(validName(" Alex "));
}
}Output
false
true06 / 15
throw reject bad parameters
If the method requires a single number of 1 to 64, check it at the entrance. throw hands the error to the caller rather than continuing to save bad data.
- Entry CheckReject if the parameter is illegal
- throwLeave it to the caller for processing
- MessageInclusion range and received value
L28Example05.java · Complete independent example
public class L28Example05 {
static void checkAmount(int amount) {
if (amount < 1 || amount > 64)
throw new IllegalArgumentException("The quantity should be 1 to 64: " + amount);
}
public static void main(String[] args) {
try { checkAmount(-1); }
catch (IllegalArgumentException e) { System.out.println(e.getMessage()); }
checkAmount(64);
System.out.println("64 Through");
}
}Output
The quantity should be 1 to 64: -1
64 Through07 / 15
finally and resource cleanup
Finishing is performed along the control path. finally is suitable for ordinary closing; resources that need to be closed are given priority by using try-with-resources to avoid writing the success and failure branches separately.
- finallyEnding on control path
- Automatic resource managementtry-with-resources
- Do not returnAvoid overwriting original exception or result
L28Example06.java · Complete independent example
import java.util.*;
public class L28Example06 {
public static void main(String[] args) {
try { Integer.parseInt("Many"); }
catch (NumberFormatException e) { System.out.println("Requires integer"); }
finally { System.out.println("This attempt ends"); }
try (Scanner scanner = new Scanner("3")) {
System.out.println(scanner.nextInt());
}
}
}Output
Requires integer
This attempt ends
308 / 15
Detected and Unchecked Abnormalities
Checked exceptions are required by the compiler to be caught or declared in the method signature. Unchecked exceptions usually indicate that parameters or program state do not conform to the contract.
- IOExceptionCompiler requires processing or declaration
- RuntimeExceptionUnchecked exception
- Inspection methodDifferent does not mean different importance
L28Example07.java · Complete independent example
public class L28Example07 {
static void read() throws java.io.IOException {
throw new java.io.IOException("Demo read failed");
}
public static void main(String[] args) {
try { read(); }
catch (java.io.IOException e) { System.out.println(e.getMessage()); }
}
}Output
Demo read failed| Category | Example | Common processing |
|---|---|---|
| Detected exception | IOException | catch or throws |
| Unchecked exception | IllegalArgumentException | Modify parameter contract |
| Unchecked exception | NumberFormatException | User input can be captured |
09 / 15
Custom abnormal expression field failure
When multiple backpack rules may fail, a custom exception lets the caller know explicitly that this is an issue with the inventory domain.
- InventoryExceptionExpressing a type of field failure
- extends ExceptionThis is designed as a checked exception
- CallerExplicitly choose how to restore
L28Example08.java · Complete independent example
class InventoryException extends Exception {
InventoryException(String message) { super(message); }
}
public class L28Example08 {
static int withdraw(int stock, int amount) throws InventoryException {
if (stock < 0 || amount <= 0 || amount > stock)
throw new InventoryException("Insufficient inventory");
return stock - amount;
}
public static void main(String[] args) {
try { withdraw(0, 1); }
catch (InventoryException e) { System.out.println(e.getMessage()); }
}
}Output
Insufficient inventory10 / 15
Error messages must be actionable
Good news allows users to know what happened and how to change it next, and also allows programmers to find corresponding operations.
- What happenedAdd operation failed
- Which inputItem name or quantity
- Next stepProvide legal scope and correction suggestions
| Message | Problem | Improvement |
|---|---|---|
| Error | No context | Quantity must be an integer: many |
| failed | No operation name | Failed to add diamond: item name is empty |
| Wrong range | No legal scope | Quantity must be between 1 and 64: 80 |
11 / 15
Abnormal paths must also be tested
Only testing normal input is equivalent to only coloring the armor. True blast armor is meant to withstand impacts in the wrong path.
- Normal operationIncrease in quantity
- Parsing failedChinese quantities cannot be converted to integers
- Status comparisonInventory will not be changed for any failure
L28Example10.java · Section 1/2, sequentially connected to the same file
import java.util.*;
public class L28Example10 {
static void addItem(Map<String, Integer> inventory,
String item, int amount) {
if (inventory == null)
throw new IllegalArgumentException("Inventory cannot be null");
if (item == null || item.isBlank())
throw new IllegalArgumentException("Item name cannot be empty");
if (amount < 1 || amount > 64)
throw new IllegalArgumentException("The single quantity must be within 1 to 64 between: " + amount);
String key = item.strip();
Integer old = inventory.get(key);
if (inventory.containsKey(key) && (old == null || old < 0))
throw new IllegalArgumentException("The original inventory record is illegal: " + key);
long total = (long) (old == null ? 0 : old) + amount;
if (total > Integer.MAX_VALUE)
throw new IllegalArgumentException("The cumulative inventory exceeds the upper limit of the integer: " + key);
inventory.put(key, (int) total);
}
static String process(Map<String, Integer> inventory,
String item, String amountText) {
if (item == null || item.isBlank()) return "Item name cannot be empty";
if (amountText == null || amountText.isBlank()) return "Quantity cannot be empty";
String key = item.strip();
try {
int amount = Integer.parseInt(amountText.strip());
addItem(inventory, key, amount);
return key + " Added successfully Quantity=" + inventory.get(key);L28Example10.java · Paragraph 2/2, sequentially connected to the same file
} catch (NumberFormatException error) {
return "Quantity must be an integer: " + amountText;
} catch (IllegalArgumentException error) {
return error.getMessage();
}
}
public static void main(String[] args) {
Map<String, Integer> inventory = new HashMap<>(Map.of("diamond", 3));
Map<String, Integer> before = new HashMap<>(inventory);
System.out.println(process(inventory, "diamond", "-2"));
System.out.println(inventory.equals(before));
}
}Output
The single quantity must be within 1 to 64 between: -2
true| Enter | Path | Expected |
|---|---|---|
| Diamond 3 | Success | Quantity increased by 3 |
| Lots of diamonds | Parsing failed | Prompt integer data unchanged |
| Diamond -2 | Range failed | Prompt 1 to 64 data remains unchanged |
| Empty name 5 | Verification failed | Prompt name data remains unchanged |
| Diamond 64 | Boundary success | Allow adding |
12 / 15
Challenge Blueprint Security Backpack Manager
The challenge program is called SafeInventory. Each operation returns a friendly message and the inventory is modified only if all checks are passed.
- processVerify text and convert results
- addItemMaintain inventory rules
- Write at the endModify only after passing all verifications
Acceptance sequence
- Diamond 3 was added successfully, and the cumulative quantity is 3.
- The quantity text "many" prompt must be an integer, and the inventory remains unchanged.
- Quantity-2 prompts a single range of 1 to 64, and the inventory remains unchanged.
- Empty names are rejected before parsing and the inventory is unchanged.
- Add diamond 64 again, and the total is 67; distinguish between the single upper limit and the cumulative inventory.
13 / 15
safety backpack program
Create a new SafeInventory.java, compile and run using Java 21.
- Single 1 to 64Quantity range per request
- Cumulative inventoryCan exceed 64, subject to the upper limit of int
- Friendly resultsSuccess or explicit rejection
SafeInventory.java · Section 1/2, sequentially connected to the same file
import java.util.*;
public class SafeInventory {
static void addItem(Map<String, Integer> inventory,
String item, int amount) {
if (inventory == null)
throw new IllegalArgumentException("Inventory cannot be null");
if (item == null || item.isBlank())
throw new IllegalArgumentException("Item name cannot be empty");
if (amount < 1 || amount > 64)
throw new IllegalArgumentException("The single quantity must be within 1 to 64 between: " + amount);
String key = item.strip();
Integer old = inventory.get(key);
if (inventory.containsKey(key) && (old == null || old < 0))
throw new IllegalArgumentException("The original inventory record is illegal: " + key);
long total = (long) (old == null ? 0 : old) + amount;
if (total > Integer.MAX_VALUE)
throw new IllegalArgumentException("The cumulative inventory exceeds the upper limit of the integer: " + key);
inventory.put(key, (int) total);
}
static String process(Map<String, Integer> inventory,
String item, String amountText) {
if (item == null || item.isBlank()) return "Item name cannot be empty";
if (amountText == null || amountText.isBlank()) return "Quantity cannot be empty";
String key = item.strip();
try {
int amount = Integer.parseInt(amountText.strip());
addItem(inventory, key, amount);
return key + " Added successfully Quantity=" + inventory.get(key);SafeInventory.java · Section 2/2, sequentially connected to the same file
} catch (NumberFormatException error) {
return "Quantity must be an integer: " + amountText;
} catch (IllegalArgumentException error) {
return error.getMessage();
}
}
public static void main(String[] args) {
Map<String, Integer> inventory = new HashMap<>();
System.out.println(process(inventory, "diamond", "3"));
System.out.println(process(inventory, "diamond", "Many"));
System.out.println(process(inventory, "diamond", "-2"));
System.out.println(process(inventory, " ", "5"));
System.out.println(process(inventory, "diamond", "64"));
System.out.println("Final inventory=" + inventory.get("diamond"));
}
}Output
diamond Added successfully Quantity=3
Quantity must be an integer: Many
The single quantity must be within 1 to 64 between: -2
Item name cannot be empty
diamond Added successfully Quantity=67
Final inventory=6714 / 15
Expansion tasks and clearance review
The job submits a successful path and at least three failed paths simultaneously. Write a sentence for each catch why it can be restored correctly.
- Path to successAt least one true addition
- Failure pathParsing, range, empty name
- catch reasonExplain why it can be restored
Third gear operation
- Wooden Pickaxe: Read age safely, reject non-integer and negative numbers.
- Iron Pickaxe: Analyze x y z coordinates, and retain the old position when any item is illegal.
- Diamond Pickaxe: Record the number of occurrences of each error and output a diagnostic report at the end.
| Self-evaluation | Can | Still need to practice |
|---|---|---|
| I can read abnormal clues | □ | □ |
| I will catch specific exceptions | □ | □ |
| I can test it unchanged after failure | □ | □ |
15 / 15
Own acceptance record
Beautiful output is the starting point, and being able to explain boundaries is considered mastery. Select one case each from normal, borderline and error, write down your expectations before running, and leave evidence after running.
| Category | The operation you selected | Check key points |
|---|---|---|
| Normal | A common input or a successful action | Is the result consistent line by line? |
| Border | Range endpoints and adjacent values | Is there one more step or one less thing? |
| Error | Illegal quantity, missing object or bad data | Whether it is explicitly rejected and whether the status is maintained |
- Bug records: triggering conditions, actual phenomena, causes, and minimum repairs.
- Illustrated record: describe the starting point, end point and meaning of each arrow.
- Adaptation record: only change one rule, and modify expectations and tests at the same time.
TAKE IT WITH YOU
Take the lesson offline
The complete lesson, code, diagrams and exercises, in your preferred language.