Saltar a contenido

12 - Reading Other People's Code

What this session is

About 45 minutes. You'll learn the strategy for reading code you didn't write. This is a different skill from writing your own. Master it and your effective competence jumps a level.

The mistake most beginners make

You open a new codebase and start reading the first file you see, trying to understand every line. By line 50 you're lost; by line 200 you've given up.

This doesn't work because real code isn't a story - it's a graph. Every method calls others. Every class is defined somewhere else. Trying to load it all into your head is impossible, even for experienced engineers.

The trick is to not try. Pick a small thread; follow only it; let the rest stay fuzzy.

The five-minute orientation

For any new Java project:

  1. Read the README. What does this project DO? If you can't answer in one sentence, the README is incomplete - try another project.

  2. List the top-level directories. Typical Java layout:

  3. src/main/java/... - the code.
  4. src/main/resources/ - config, templates, static files.
  5. src/test/java/... - tests.
  6. pom.xml (Maven) or build.gradle.kts (Gradle).
  7. .github/workflows/ - CI.
  8. docs/, examples/, LICENSE, CONTRIBUTING.md.

  9. Open pom.xml / build.gradle. What's the artifactId? Java version? Major dependencies (Spring? Jackson? Guava?)? Tells you the ecosystem.

  10. Find the entry point. For an app, look for public static void main. For a library, look at the top-level package's most-public classes (named with the project name often: Greet, Hello, etc.).

  11. Read one test file. Tests show you what the code is supposed to do with concrete examples. Often clearer than the code being tested.

After this, write a one-paragraph summary of what the project does. If you can't, repeat.

Tools for reading

  • IntelliJ IDEA's "Find Usages" and "Go to Definition" - Cmd-B / Ctrl-B to jump to definition; Alt-F7 to find all references. The single biggest productivity tool for reading Java.
  • javadoc browsing - most libraries publish their Javadoc online (search " javadoc"). Skim the package summary before diving into source.
  • grep -r 'pattern' src/ - old-school but unbeatable for finding all uses of a string.
  • mvn dependency:tree - see what depends on what.
  • mvn test -Dtest=ClassName#methodName - run one specific test to watch it execute.
  • Reading recent merged PRs on GitHub. Often the clearest way to understand a project.

A worked example

Let's read a piece of the standard library: String.indexOf.

  1. In any class, type String s = "hello"; s.indexOf and Cmd-B on indexOf (in IntelliJ). It jumps to String.indexOf(String str) in String.java.
  2. The method body delegates to a static indexOf. Cmd-B again.
  3. The static indexOf is a few dozen lines, with an SIMD-accelerated fast path. Read the top, skim the loop.
  4. Recognize: "scans the source string looking for the target; returns the position or -1." That's enough.
  5. Confirm with the JDK's tests under test/jdk/java/lang/String/. Find IndexOfTest.java. Read three cases.

Five minutes; you understood enough.

Things that look scary in Java codebases

  • Annotations (@Override, @Test, @Inject, @Autowired, framework-specific) - metadata read by frameworks. Recognize the common ones; don't worry about framework specifics unless using that framework.
  • Generics with bounds - <T extends Comparable<? super T>> reads like noise the first time; it's PECS (page 09).
  • Streams - list.stream().filter(...).map(...).collect(...). A pipeline; read left to right.
  • Lambdas and method references - x -> x.length() and String::length. Inline functions; everywhere in modern Java.
  • Reflection - clazz.getDeclaredMethod("foo").... Frameworks (Jackson, Spring) use it heavily. Recognize and skip on first read.
  • Inner classes / anonymous classes - class Outer { class Inner { ... } } or new Runnable() { public void run() { ... } }. Older style; modern code prefers lambdas where possible.
  • @FunctionalInterface - marks an interface with exactly one abstract method, usable with lambdas.

You'll hit things you don't recognize. Knowing when to dig in vs skim past is the skill.

Reading vs understanding

Two distinct things: - Reading code: following what it does, line by line. - Understanding code: knowing why it's shaped that way.

You don't need understanding to contribute. A first PR often involves reading 1000 lines, understanding 100, modifying 5.

Exercise

No new code. Reading.

Pick a small Java project on GitHub. Suggestions:

  • Netflix/Hollow - large-ish, but well-organized. Skip.
  • SeleniumHQ/htmlunit - older codebase, classic OOP Java.
  • Try smaller: apache/commons-lang3 - utility classes. Each is small and self-contained.
  • google/guava - Google's Java utility library. Big overall but each module is small.
  • pcj/orbit - distributed actor framework, mid-size.
  • hexops/dyzio - modern, smaller utility lib.

For sheer beginner-friendliness, commons-lang3 is excellent - pick one utility class (StringUtils, say) and trace it.

Apply the orientation: 1. README → what does it do? 2. Layout → standard Maven? 3. pom.xml → dependencies? 4. Pick one class, trace one method. 5. Read three tests for that method.

Write a paragraph: what does this do? How is it organized? What surprised you?

What you might wonder

"What if I don't understand something?" Write it down, skip, keep going. Often the thing that confused you on day 1 makes sense after a week. If it still doesn't, ask in the project's discussion - but try for an hour first.

"Huge projects like Spring Boot - where do I start?" A sub-module. Spring has dozens of small repos under spring-projects/. Pick one (spring-pulsar is small) rather than spring-framework itself.

Done

You can now: - Apply a five-minute orientation to any Java project. - Use IntelliJ navigation, Javadoc, and grep to read efficiently. - Distinguish reading from understanding. - Recognize common "looks scary, isn't" patterns. - Pick a small project and summarize what it does.

Next: Picking a project →

Comments