Unit 03 · lesson
Compiler Error, Exception, or Wrong Answer?
Debugging gets faster when you classify the failure before trying to fix it.
Use three broad buckets first:
compile-time failure
runtime failure / exception
logic failure / wrong behavior
The categories are not the entire science of software failure, but they are a strong first filter.
Case 1: the compiler refuses the source
void main() {
int count = "7";
IO.println(count);
}
No valid runnable program is produced from this source. Fixing runtime input cannot solve it because execution never begins.
Case 2: source is valid but data breaks an assumption
void main() {
String text = "seven";
int count = Integer.parseInt(text);
IO.println(count);
}
The program can compile. During execution, parsing fails.
The useful question is not "How do I remove the exception?" It is:
What assumption about runtime data was false?
Case 3: everything runs and the answer is wrong
void main() {
int passed = 7;
int total = 10;
double rate = passed / total * 100;
IO.println(rate);
}
No syntax error. No exception. Wrong numeric behavior because integer division occurs before the value reaches the double variable.
Logic failures often require stronger evidence because the runtime has no reason to complain.
Use the failure boundary
For each bug, locate the earliest boundary where evidence diverges from expectation.
source text
|
compiler/type rules
|
runtime input
|
state transition / calculation
|
output
If source is rejected, do not investigate output.
If parsing fails, do not rewrite an unrelated formula.
If output is wrong, trace the values that produced it instead of changing code randomly.
The smallest responsible change
Suppose the rate program prints 0.0.
Weak debugging:
- change multiple variable types;
- change formula order;
- add extra output;
- search for a different formula;
- rerun until
70.0appears.
Stronger debugging:
- preserve Version 1;
- identify the integer division boundary;
- predict the smallest correction;
- change one operand to floating-point division;
- rerun the original case;
- run at least one regression case such as 1/4.
Now the evidence connects cause to correction.
Failure classification drill
Classify each scenario before attempting any fix.
- Missing closing quote in a String literal.
Integer.parseInt("12x").- Rectangle area calculated using addition.
- Accessing an array index that does not exist.
- Comparing String content with
==and getting inconsistent behavior. - Referring to a variable name that was never declared.
For each, state what additional evidence you would want. The category is a starting hypothesis, not a substitute for observation.
Create a three-failure specimen
Build one small program in the Java Playground and deliberately create three versions:
- Version C: a compile-time failure;
- Version R: a runtime failure;
- Version L: a logic failure.
For each version preserve:
source fragment:
expected stage/result:
actual evidence:
classification:
responsible line or boundary:
smallest correction:
Then create Version F, the corrected final program, and run the original intended case plus one additional case.
That artifact becomes the foundation for the checkpoint. You are no longer trying to demonstrate that you never make mistakes. You are demonstrating that you can make program behavior explainable.