Java errors become easier to fix when you identify the phase and contract involved. A compiler message describes a source or type-checking problem; a launch message can describe class lookup; an exception reports something that happened during execution. Read the first useful diagnostic and its location before changing unrelated code. The reference below groups common failures, and the worked programs demonstrate explicit repairs for numeric input, nullable values, and array bounds. Fix the cause rather than merely hiding the final symptom.
Compile-time and launch diagnostics
| Diagnostic | First check |
|---|---|
| cannot find symbol | Spelling, scope, imports, and the available dependency |
| incompatible types | Declared types and the actual returned value |
| Public class filename mismatch | Exact public class and .java filename |
| Could not find or load main class | Qualified class name and classpath root |
| UnsupportedClassVersionError | Compiler target versus runtime release |
| NoClassDefFoundError | Required runtime class or failed initialization |
Rebuild successfully before launching changed source. An older class file can remain after a failed compile and make it look as though an invalid edit ran. Missing imports and missing dependency JARs are different problems; an import does not download code.
Read a stack trace from the failure inward
An exception's type names the failure category, its message may identify a value or rule, and stack frames locate calls leading to the throw. Start with the relevant application frame, then follow the cause chain when a framework wraps the error. Do not log only a vague error happened string. Reproduce the same input and inspect the operation at that location before deciding whether to validate, change the calculation, or adjust configuration.
Handle invalid numbers at the input boundary
Integer.parseInt rejects text outside the supported integer representation or range with NumberFormatException. A user can often correct that input, so report a useful message and decide whether to retry. Do not catch every Exception and substitute zero, because that can turn invalid input into a valid-looking order. Parsing success still does not establish a domain rule such as positive quantity; validate that separately after obtaining the number.
Separate nullable values from required values
NullPointerException usually means code tried to use a reference when no object was present. Identify why the reference is null before adding scattered checks. If absence is valid, model it with an explicit response or appropriate Optional return. Objects.equals compares potentially nullable references safely. If a value is required, validate it at the boundary rather than replacing null with an empty object that conceals missing configuration or data.
Validate bounds and preserve collection contracts
Array indices must be at least zero and less than length. String.charAt uses its own valid range, and substring has specific start and end rules. A loop using less-than-or-equal with array length eventually reaches an invalid index. UnsupportedOperationException can indicate editing an unmodifiable collection. ConcurrentModificationException can indicate unsupported mutation during iteration, and ClassCastException indicates an incompatible runtime cast. Fix the relevant contract instead of treating all these exceptions as a generic null problem.
Choose a repair with a regression case
For ArithmeticException from integer division by zero, validate the divisor or define the intended absence result. For a missing runtime dependency, repair the runtime classpath rather than changing arithmetic. For an unsafe cast, use a known interface or a checked pattern when appropriate. After fixing a failure, test the original input and an ordinary valid input. A regression check confirms that the repair handles the failing case without quietly damaging normal behavior.
Practice tasks and checks
Create a small failing case for an array loop using the wrong inclusive boundary, then fix the condition and test an empty array too. For numeric input, test malformed text, an out-of-range integer string, zero, and a valid positive value. Keep parse failure and domain rejection distinct. For null handling, decide whether absence is allowed before choosing a fallback. Finally, deliberately launch a packaged class using the wrong classpath root and classify the diagnostic as lookup rather than a source-type error. Record the original cause, the focused repair, and its regression case. This makes the error reference a diagnostic method rather than a list of messages to suppress.
Java Summary
- Identify compile, launch, and execution failures separately.
- Validate input at a boundary with a meaningful response.
- Preserve useful causes and test the original failing case.
- Continue with debugger-based diagnosis when these examples are clear.
Java Examples
Each example shows the code, the output it produces and what each part does.
Reject malformed numeric input clearly
Save this program as NumberInputFix.java. Compile it with javac NumberInputFix.java and run it with java NumberInputFix.
Expected output:
The malformed text fails during parsing and reaches the specific catch. Zero parses successfully but fails the separate positive-quantity rule. Six satisfies both steps and is accepted. This distinction prevents a parser catch from being mistaken for all validation. The method reports each outcome explicitly; it does not silently substitute a valid-looking default for bad text.
public class NumberInputFix {
static void report(String text) {
try {
int quantity = Integer.parseInt(text);
if (quantity <= 0) {
System.out.println("Quantity must be positive");
return;
}
System.out.println("Accepted: " + quantity);
} catch (NumberFormatException error) {
System.out.println("Enter a whole-number quantity");
}
}
public static void main(String[] args) {
report("4x");
report("0");
report("6");
}
}Enter a whole-number quantity
Quantity must be positive
Accepted: 6Compare nullable content without dereferencing it
Save this program as NullComparisonFix.java. Compile it with javac NullComparisonFix.java and run it with java NullComparisonFix.
Expected output:
Objects.equals handles null references, returning false when one is null and the other is not, and true when both are null. The display expression then chooses an explicit absence message. Calling supplied.equals would dereference null and fail. This repair is suitable because absence is accepted by this example's contract; it should not be used to conceal a required configuration value that must instead be rejected.
import java.util.Objects;
public class NullComparisonFix {
public static void main(String[] args) {
String supplied = null;
System.out.println(Objects.equals(supplied, "READY"));
System.out.println(Objects.equals(supplied, null));
String display = supplied == null ? "Not supplied" : supplied;
System.out.println(display);
}
}false
true
Not suppliedKeep array access inside its range
Save this program as ArrayBoundsFix.java. Compile it with javac ArrayBoundsFix.java and run it with java ArrayBoundsFix.
Expected output:
The loop visits only indices zero and one because its condition is strictly below length. lookup treats index two as outside the range and returns the documented response before reading the array. Negative indices are rejected too. The method assumes names is non-null; a null array is a different contract issue from an invalid index and should be handled according to the caller's requirements.
public class ArrayBoundsFix {
static String lookup(String[] names, int index) {
if (index < 0 || index >= names.length) return "Unknown position";
return names[index];
}
public static void main(String[] args) {
String[] names = {"North", "South"};
for (int i = 0; i < names.length; i++) System.out.println(names[i]);
System.out.println(lookup(names, 2));
}
}North
South
Unknown positionJava FAQ
Should I catch Exception around the whole program?
Not as a substitute for understanding errors. Catch relevant failures where you can recover or report them meaningfully. A broad top-level reporting boundary can be appropriate, but it should preserve useful causes and not pretend failed work succeeded.
Why did adding an import not fix a missing library?
An import only changes source name resolution. The dependency must exist on the compiler and runtime search paths as required. Check the build declaration and launch configuration separately.
What does "possible lossy conversion" mean?
You're assigning a value to a type that might not be able to hold it, such as a double into an int or a long into an int. Either change the variable's type, or cast explicitly with (int) after deciding that dropping the fraction or high bits is acceptable.
What does "non-static variable cannot be referenced from a static context" mean?
Code in a static method, usually main, tried to use an instance field or method directly. Static code has no object to read the field from. Create an object first, Shop shop = new Shop();, and call shop.count, or make the member static if it truly belongs to the class.
What does "unreachable statement" mean?
The compiler found code that can never run, typically a statement after return, break, continue or throw in the same block, or after an infinite loop with no exit. Delete the dead code or move it before the statement that ends the block.
Java Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Which failure can happen before execution because of source type mismatch?
Why is quantity zero not a NumberFormatException?
Java Quiz
2 questions to check what you learned.
What is the last valid index of a nonempty array?
- length - 1
- length
- 1 for every array
What should follow a concrete error repair?
- A regression test for the original failure
- Only hiding the message
- Changing every class name