1.08 Documentation with Comments
Write comments to explain code and document method requirements.
1. Reference Guide
Javadoc Template and Tags
/**
* Brief description of what the method does.
*
* More detailed explanation if needed, including algorithm
* information, usage notes, or important behaviors.
*
* @param paramName description of the parameter
* @return description of what is returned
*/
| Tag | Describes |
|---|---|
@param |
A parameter the method accepts |
@return |
The value the method returns |
@throws |
An exception the method might throw |
Preconditions and Postconditions
| Term | Meaning |
|---|---|
| Precondition | What must be true BEFORE the method is called. There is no expectation the method checks this itself. |
| Postcondition | What will be true AFTER the method completes successfully — in terms of the return value or the object’s attributes. |
Documentation Best Practices
| Do | Don’t |
|---|---|
| Be specific: “sets GPA to the given value, rounded to one decimal” | Be vague: “processes the data” |
| Document non-obvious logic and edge cases (null? empty array?) | Over-document a simple getter/setter that the name already explains |
| Update docs the moment code changes | Let documentation go stale |
AP Exam Connections
- Know the difference between
//,/* */, and/** */ - FRQs reward documenting complex methods, explaining logic, and specifying parameter constraints — it demonstrates programming maturity to the scorer
2. LxD Cycle Process
Empathize: I noticed students treat comments as an afterthought — something added at the end, if there’s time, to satisfy a rubric line. Many either skip documentation entirely or over-document trivial getters/setters while leaving genuinely complex methods unexplained. They also confuse “what a precondition is” with “code that checks the precondition.”
Define:
- POV: CSA students need to see documentation as communication, not decoration, because FRQ scorers and real teammates both rely on comments to understand intent that the code alone doesn’t show.
- Learning Goal: Students will write correct Javadoc comments (
@param,@return,@throws), state preconditions and postconditions for a method, and judge when documentation is genuinely needed versus when it is noise.
Ideate:
- HMW Question: How might we get students to document the why behind a method instead of restating the what the code already says?
- Activity: Warm-Up — we need 2 volunteers to come up and play a game demonstrating how much guesswork is required to use a method with no documentation versus one with clear Javadoc.
Prototype & Test: In a trial run, students could recite the three comment types but still wrote Javadoc with no preconditions or postconditions. I added a required precondition/postcondition block to every Code Example so the pattern becomes automatic before students reach the Hacks section.
3. College Board Requirements
Topic 1.8, Documentation with Comments, is required content on the AP Computer Science A Exam. The College Board’s official course framework defines the three comment types this lesson teaches:
“Comments are written for both the original programmer and other programmers to understand the code and its functionality, but are ignored by the compiler and are not executed when the program is run. Three types of comments in Java include /* */, which generates a block of comments; //, which generates a comment on one line; and /** */, which are Javadoc comments and are used to create API documentation.” (College Board, 2025, p. 40)
It also defines the two contract terms this lesson centers on:
“A precondition is a condition that must be true just prior to the execution of a method in order for it to behave as expected… A postcondition is a condition that must always be true after the execution of a method.” (College Board, 2025, p. 40)
4. Lesson Plan
Learning Objective: By the end of this lesson, you will be able to write Javadoc comments using @param, @return, and @throws, state preconditions and postconditions for a method, and decide when a piece of code needs documentation and when it does not.
Success Criteria: You can take an undocumented method and produce a Javadoc comment that states its purpose, its preconditions, its postconditions, and its parameters/return value — without over-documenting a method whose name and signature already make it obvious.
Tech Talk & Introduction (5 minutes)
“Code tells you HOW, documentation tells you WHY.”
Documentation serves other developers, maintainers, testers, and your own future self, who will not remember today’s logic in three months. Java has three kinds of comments:
- Single-line:
//— quick notes - Multi-line:
/* */— longer explanations - Javadoc:
/** */— generates official API documentation, and is our focus today
Why do we do this? Comments are ignored by the compiler but not by the humans who read your code next — including the AP reader scoring your FRQ.
5. Code Examples
A. Simple: Method-Level Javadoc
// CODE_RUNNER: Calculate Final Grade
// Run it, then change a value and predict the new output
public class CodeRunner1_CalculateFinalGrade {
/**
* Calculates the final grade for a student based on weighted categories.
* The grade is computed using the formula:
* (homework * 0.3) + (tests * 0.5) + (participation * 0.2)
*
* @param homework the average homework score (0.0 to 100.0)
* @param tests the average test score (0.0 to 100.0)
* @param participation the participation score (0.0 to 100.0)
* @return the weighted final grade as a percentage (0.0 to 100.0)
*/
public double calculateFinalGrade(double homework, double tests, double participation) {
return homework * 0.3 + tests * 0.5 + participation * 0.2;
}
public static void main(String[] args) {
CodeRunner1_CalculateFinalGrade calculator = new CodeRunner1_CalculateFinalGrade();
// Test the method
System.out.println("Final Grade: " + calculator.calculateFinalGrade(85.0, 92.0, 88.0));
}
}
Final Grade: 89.1
B. Intermediate: Preconditions and Postconditions as a Contract
// CODE_RUNNER: Bank Withdraw with Preconditions and Postconditions
// Run it, then change a value and predict the new output
public class CodeRunner2_BankWithdraw {
/**
* Withdraws money from the bank account.
*
* Preconditions:
* - amount must be positive
* - amount must not exceed current balance
* - account must not be frozen
*
* Postconditions:
* - balance is reduced by the withdrawal amount
* - transaction is recorded in account history
* - returns true if withdrawal successful
*
* @param amount the amount to withdraw (must be positive)
* @return true if withdrawal successful, false otherwise
*/
public boolean withdraw(double amount) {
// Local variable definitions
double balance = 500.0; // example current balance
boolean isFrozen = false; // example account state
// Preconditions: amount must be positive, not exceed balance, and account not frozen
if (amount <= 0 || amount > balance || isFrozen) {
return false; // Precondition not met
}
// Perform withdrawal
balance -= amount;
// Record transaction (for now, just print it)
System.out.println("Transaction: Withdraw $" + amount);
System.out.println("New balance: $" + balance);
// Postcondition: balance reduced, transaction recorded
return true;
}
public static void main(String[] args) {
CodeRunner2_BankWithdraw bank = new CodeRunner2_BankWithdraw();
bank.withdraw(100.0);
}
}
Transaction: Withdraw $100.0
New balance: $400.0
true
C. Complex: Class-Level Documentation
Classes also need documentation explaining their overall purpose, key responsibilities, a usage example, and @author/@version/@since tags.
// CODE_RUNNER: Student Class with Javadoc
// Run it, then change a value and predict the new output
import java.util.ArrayList;
import java.util.HashMap;
/**
* Represents a student in the school management system.
*
* This class maintains student information including personal details,
* academic records, and enrollment status. It provides methods for
* updating grades, managing course enrollment, and generating reports.
*
* Example usage:
* <pre>
* Student alice = new Student("Alice Johnson", 12);
* alice.enrollInCourse("AP Computer Science");
* alice.updateGrade("Math", 95.5);
* System.out.println(alice.getGPA());
* </pre>
*
* @author Your Name
* @version 1.0
* @since 2024-01-15
*/
public class CodeRunner3_Student {
private String name;
private int gradeLevel;
private ArrayList<String> courses;
private HashMap<String, Double> grades;
public CodeRunner3_Student(String name, int gradeLevel) {
this.name = name;
this.gradeLevel = gradeLevel;
this.courses = new ArrayList<>();
this.grades = new HashMap<>();
}
public void enrollInCourse(String course) {
courses.add(course);
}
public void updateGrade(String course, double grade) {
grades.put(course, grade);
}
public double getGPA() {
if (grades.isEmpty()) return 0.0;
double sum = 0;
for (double g : grades.values()) {
sum += g;
}
return sum / grades.size();
}
public static void main(String[] args) {
CodeRunner3_Student alice = new CodeRunner3_Student("Alice Johnson", 12);
alice.enrollInCourse("AP Computer Science");
alice.updateGrade("Math", 95.5);
System.out.println("GPA: " + alice.getGPA());
}
}
95.5
D. Complex: Knowing When Not to Document
A simple accessor whose name already says everything doesn’t need a comment. A method with validation, normalization, and a thrown exception does.
// CODE_RUNNER: Name Holder with Javadoc
// Run it, then change a value and predict the new output
public class CodeRunner4_NameHolder {
private String name;
/**
* Gets the student's name.
*
* @return the name of the student
*/
public String getName() {
return name;
}
/**
* Updates the student's name with validation and normalization.
*
* Trims whitespace and validates that the name contains only
* letters, spaces, hyphens, and apostrophes.
*
* @param name the new name (will be normalized)
* @throws IllegalArgumentException if name is null or empty
*/
public void setNameWithValidation(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Name cannot be null or empty");
}
this.name = name.trim();
}
public static void main(String[] args) {
CodeRunner4_NameHolder n = new CodeRunner4_NameHolder();
n.setNameWithValidation(" Alice ");
System.out.println(n.getName());
}
}
6. Hacks & Practice Tasks
Submission Safety Rules (Read First)
[!IMPORTANT] To avoid grading errors, follow these rules exactly:
- Every Javadoc block you submit must include a precondition and a postcondition section.
- Run every code cell and leave the output visible before submitting.
- Do not document a trivial getter/setter — explain why you chose not to.
Popcorn Hack #1: Fix the Documentation (5 minutes)
[!TIP] Write the precondition and postcondition in plain English before you touch a single Javadoc tag.
Task: The following code has poor documentation. Rewrite it with proper Javadoc comments including preconditions and postconditions.
// CODE_RUNNER: Poor Documentation Example
// Run it, then change a value and predict the new output
// NOTE: This example shows POOR documentation - try to improve it!
public class CodeRunner5_PoorDocumentation {
// Does stuff with numbers
public int doSomething(int[] nums) {
int result = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0 && nums[i] % 2 == 0) {
result += nums[i];
}
}
return result;
}
public static void main(String[] args) {
CodeRunner5_PoorDocumentation calculator = new CodeRunner5_PoorDocumentation();
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
System.out.println("Result: " + calculator.doSomething(numbers));
}
}
Check your answer below!
/**
* Calculates the sum of all positive even integers in the given array.
* <p>
* This method loops through each element of {@code nums} and adds it to a running total
* only if the element is greater than zero and evenly divisible by two.
* The method then returns the resulting sum.
* </p>
*
* <p><b>Preconditions:</b></p>
* <ul>
* <li>{@code nums} must not be {@code null}.</li>
* <li>{@code nums} may contain any integers (positive, negative, or zero).</li>
* </ul>
*
* <p><b>Postconditions:</b></p>
* <ul>
* <li>Returns the sum of all positive even numbers in {@code nums}.</li>
* <li>If there are no positive even numbers, returns {@code 0}.</li>
* </ul>
*
* @param nums an array of integers to evaluate
* @return the sum of all positive even integers in {@code nums}; {@code 0} if none exist
*
* <p><b>Example usage:</b></p>
* <pre>
* int[] numbers = {1, 2, 3, 4, -6};
* int result = doSomething(numbers); // result = 6
* </pre>
*/
public int doSomething(int[] nums) {
int result = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0 && nums[i] % 2 == 0) {
result += nums[i];
}
}
return result;
}
Popcorn Hack #2: Write Class Documentation (5 minutes)
Your Mission: Add Javadoc comments to document this GradeBook class!
What to include:
- What does this class do? (purpose)
- What are the main features? (key methods)
- How would someone use it? (example)
- Tags:
@author,@version,@since
// TODO: Add your class-level Javadoc here!
// Hint: Start with /** and end with */
public class GradeBook {
private HashMap<String, Double> assignments;
private HashMap<String, Double> categoryWeights;
private double extraCredit;
// TODO: Document each method too!
public void addAssignment(String category, String name, double score) { }
public void setCategoryWeight(String category, double weight) { }
public double calculateFinalGrade() { }
public String generateReport() { }
}
Check your answer below!
/**
* Manages student grades and calculates final grades based on weighted categories.
*
* This class allows teachers to track assignments across different categories
* (like homework, tests, projects) and calculate final grades using custom weights.
*
* Key Features:
* - Store assignments by category
* - Apply custom weights to each category
* - Track extra credit points
* - Generate grade reports
*
* Usage Example:
* GradeBook myGrades = new GradeBook();
* myGrades.setCategoryWeight("Homework", 0.30);
* myGrades.setCategoryWeight("Tests", 0.70);
* myGrades.addAssignment("Homework", "HW1", 95.0);
* double finalGrade = myGrades.calculateFinalGrade();
*
* @author Your Name
* @version 1.0
* @since 2025-10-06
*/
public class GradeBook {
private HashMap<String, Double> assignments;
private HashMap<String, Double> categoryWeights;
private double extraCredit;
/**
* Adds an assignment score to a specific category.
*
* @param category the category name (e.g., "Homework", "Tests")
* @param name the assignment name
* @param score the score earned (0-100)
*/
public void addAssignment(String category, String name, double score) { }
/**
* Sets the weight for a grade category.
*
* @param category the category name
* @param weight the weight as a decimal (e.g., 0.30 for 30%)
*/
public void setCategoryWeight(String category, double weight) { }
/**
* Calculates the final weighted grade including extra credit.
*
* @return the final grade as a percentage
*/
public double calculateFinalGrade() { }
/**
* Generates a formatted report of all grades and categories.
*
* @return a String containing the grade report
*/
public String generateReport() { }
}
Homework Hack
Submission form: https://docs.google.com/forms/d/e/1FAIpQLSepOCmW6KeE7jw4f80JO4Kad5YWeDUHKTpnNxnCPTtj9WEAsw/viewform?usp=header
Part 1: Documentation Analysis. Rewrite the poorly written code below with proper Javadoc comments. Submit your improved version and a brief explanation of what you improved.
// CODE_RUNNER: Commented Out Code Example
// Run it, then uncomment the code and predict the new output
// NOTE: This example shows code that has been commented out
public class CodeRunner7_CommentedOutCode {
/*
public static void main(String args[]){
int x=5;
int y=10;
int z=add(x,y);
System.out.println("ans is "+z);
}
static int add(int a,int b){
return a+b;
}
*/
public static void main(String[] args) {
System.out.println("This code is currently commented out.");
System.out.println("Try uncommenting the code above and running it!");
}
}
Part 2: Document a Complex Method. Write complete Javadoc documentation (including preconditions and postconditions) for this method:
// CODE_RUNNER: Enroll Student Method
// Run it, then change a value and predict the new output
public class CodeRunner8_EnrollStudent {
public boolean enrollStudent(String studentId, String courseCode, int semester) {
Student student = findStudentById(studentId);
if (student == null) return false;
Course course = findCourseByCode(courseCode);
if (course == null) return false;
if (course.isFull()) return false;
if (student.hasScheduleConflict(course)) return false;
if (!student.hasPrerequisites(course)) return false;
if (student.getCreditHours() + course.getCreditHours() > 18) return false;
student.addCourse(course);
course.addStudent(student);
recordEnrollmentTransaction(studentId, courseCode, semester);
return true;
}
}
Part 3: Reflection Questions.
- Why is documentation more important in team projects than solo projects?
- Give an example of when a method SHOULD be documented and when it SHOULD NOT.
Submit: A Jupyter notebook or Java file with all three parts completed.
Challenge Problems (Extra Credit)
- Document a Recursive Method — write complete documentation for a recursive method including base case, recursive case, and complexity analysis.
- Team Documentation Standard — create a style guide covering when to document, required tags per method type, and common mistakes to avoid.
- Documentation Detective — find a poorly documented open-source class, write improved documentation for it, and submit a before/after comparison.
Grading Plan (1 Point Total)
Classroom Rubric
-
0.2 points: Popcorn completion Both Popcorn Hacks include a complete Javadoc block with
@param/@returnand an explicit precondition/postcondition section. -
0.8 points: Homework completion
- 0.3 Rewritten documentation: The improved
stuffclass has clear Javadoc and an explanation of the changes. - 0.4 Complex method documentation:
enrollStudentdocumentation specifies every precondition (valid IDs, room in course, no conflicts, prerequisites, credit limit) and the postcondition for both the true and false return paths. - 0.1 Reflection: Both reflection questions are answered with a concrete example, not just a general statement.
- 0.3 Rewritten documentation: The improved
Quick Validation Checklist
- Present:
@param,@return, and (where applicable)@throwstags - Present: an explicit precondition and postcondition section in every Javadoc block
- Absent: documentation on trivial one-line getters/setters
- Present: a specific, non-vague description for every documented method
7. Lesson Revisions & Feedback Evidence
Feedback Received: Peer reviewers pointed out that one of the original “GOOD” code examples did not actually compile (it referenced this.name and a normalizeName helper inside a JShell top-level method, which is treated as static), and that the lesson introduced preconditions/postconditions in prose long before showing them inside real Javadoc.
Revision Made: I rewrote the broken example as a real, compiling NameHolder class and moved the precondition/postcondition definitions into the Reference Guide so every Code Example that follows already shows them inside a working Javadoc block.
Additional Refinement: The original lesson scattered two Popcorn Hacks and a three-part homework across six separate sections. I consolidated all practice into a single Hacks & Practice Tasks section with explicit submission safety rules, matching the structure used across the rest of Unit 1.
8. Reference List
College Board. (2025). AP Computer Science A: Course and exam description. https://apcentral.collegeboard.org/media/pdf/ap-computer-science-a-course-and-exam-description.pdf
Knuth, D. E. (1984). Literate programming. The Computer Journal, 27(2), 97–111. https://doi.org/10.1093/comjnl/27.2.97
Outside Academic Reference
This lesson’s opening idea — that documentation is written for people, not compilers — is the founding argument of Donald Knuth’s literate programming movement: “Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want the computer to do” (Knuth, 1984, p. 97).
Submit Assignment
Need to update a submission later? Open the submissions dashboard.