Overview
Want to quickly master Java through working examples? This by-example guide teaches 95% of Java through 90 annotated code examples organized by complexity level.
What Is By-Example Learning?
By-example learning is an example-first approach where you learn through annotated, runnable code rather than narrative explanations. Each example is self-contained, immediately executable in JShell (Java's interactive shell) or as standalone classes, and heavily commented to show:
- What each line does - Inline comments explain the purpose and mechanism
- Expected outputs - Using
// =>notation to show results - Intermediate values - Variable states and object flows made visible
- Key takeaways - 1-2 sentence summaries of core concepts
This approach is ideal for experienced developers (seasonal programmers or software engineers) who are familiar with at least one programming language and want to quickly understand Java's syntax, idioms, and unique features through working code.
Unlike narrative tutorials that build understanding through explanation and storytelling, by-example learning lets you see the code first, run it second, and understand it through direct interaction. You learn by doing, not by reading about doing.
Learning Path
%% Color Palette: Blue #0173B2, Orange #DE8F05, Teal #029E73, Purple #CC78BC, Brown #CA9161
graph TD
A["Beginner<br/>Examples 1-33<br/>OOP Basics"] --> B["Intermediate<br/>Examples 34-64<br/>Practical Patterns"]
B --> C["Advanced<br/>Examples 65-90<br/>Complex Features"]
style A fill:#0173B2,color:#fff
style B fill:#DE8F05,color:#fff
style C fill:#029E73,color:#fff
Progress from fundamentals through practical patterns to advanced JVM features and modern Java capabilities. Each level builds on the previous, increasing in sophistication and introducing more Java-specific concepts.
Coverage Philosophy
This by-example guide provides 95% coverage of Java through practical, annotated examples. The 95% figure represents the depth and breadth of concepts covered, not a time estimate—focus is on outcomes and understanding, not duration.
What's Covered
- Core syntax - Variables, types, operators, control flow, methods
- Object-oriented programming - Classes, objects, inheritance, polymorphism, interfaces, abstraction
- Collections framework - List, Set, Map, Queue, generics, iterators
- Functional programming - Lambdas, method references, streams, Optional
- Exception handling - Try-catch-finally, checked vs unchecked exceptions, custom exceptions
- File I/O - NIO.2, streams, serialization, JSON
- Concurrency - Threads, synchronization, ExecutorService, CompletableFuture, virtual threads
- Testing - JUnit, Mockito, test patterns
- JVM internals - Garbage collection, memory management, bytecode, class loading
- Design patterns - Singleton, Factory, Builder, Strategy, Observer, Decorator, Dependency Injection
- Modern Java features - Records, sealed classes, pattern matching, modules, var
What's NOT Covered
This guide focuses on learning-oriented examples, not problem-solving recipes or production deployment. For additional topics:
- Deep framework knowledge - Spring, Hibernate, JavaFX covered at introductory level only
The 95% coverage goal maintains humility—no tutorial can cover everything. This guide teaches the core concepts that unlock the remaining 5% through your own exploration and project work.
How to Use This Guide
- Sequential or selective - Read examples in order for progressive learning, or jump to specific topics when switching from another language
- Run everything - Copy and paste examples into JShell or create standalone
.javafiles to see outputs yourself. Experimentation solidifies understanding. - Modify and explore - Change values, add print statements, break things intentionally. Learn through experimentation.
- Use as reference - Bookmark examples for quick lookups when you forget syntax or patterns
- Complement with narrative tutorials - By-example learning is code-first; pair with comprehensive tutorials for deeper explanations
Best workflow: Open JShell or your IDE in one window, this guide in another. Run each example as you read it. When you encounter something unfamiliar, run the example, modify it, see what changes.
Relationship to Other Tutorials
Understanding where by-example fits in the tutorial ecosystem helps you choose the right learning path:
| Tutorial Type | Coverage | Approach | Target Audience | When to Use |
|---|---|---|---|---|
| By Example | 95% through 90 examples | Code-first, annotated examples | Experienced developers | Quick language pickup, reference, language switching |
| Quick Start | 5-30% touchpoints | Hands-on project | Newcomers to Java | First taste, decide if worth learning |
| Beginner | 0-60% comprehensive | Narrative, explanatory | Complete beginners | Deep understanding, first programming language |
| Intermediate | 60-85% | Practical applications | Past basics | Production patterns, frameworks |
| Advanced | 85-95% | Complex systems | Experienced Java devs | JVM internals, distributed systems |
| Cookbook | Problem-oriented | Recipe, solution-focused | All levels | Specific problems, common tasks |
By Example vs. Quick Start: By Example provides 95% coverage through examples vs. Quick Start's 5-30% through a single project. By Example is code-first reference; Quick Start is hands-on introduction.
By Example vs. Beginner Tutorial: By Example is code-first for experienced developers; Beginner Tutorial is narrative-first for complete beginners. By Example shows patterns; Beginner Tutorial explains concepts.
By Example vs. Cookbook: By Example is learning-oriented with progressive examples building language knowledge. Cookbook is problem-solving oriented with standalone recipes for specific tasks. By Example teaches concepts; Cookbook solves problems.
Prerequisites
Required:
- Experience with at least one programming language
- Ability to run code in JShell or compile Java programs
Recommended (helpful but not required):
- Familiarity with object-oriented programming concepts (classes, inheritance, polymorphism)
- Experience with statically typed languages (C++, C#, TypeScript)
- Understanding of compilation and bytecode basics
No prior Java experience required - This guide assumes you're new to Java but experienced with programming in general. You should be comfortable reading code, understanding basic programming concepts (variables, functions, loops), and learning through hands-on experimentation.
Structure of Each Example
Every example follows this consistent format:
### Example N: Concept Name
Brief explanation of the concept in 2-3 sentences. Explains **what** the concept is and **why** it matters.
[OPTIONAL: Mermaid diagram when concept relationships need visualization]
**Code**:
```java
// Comment explaining what this section does
public class Example {
// Inline comment for each significant line
public static void main(String[] args) {
int result = operation(); // => expected_output_value
// Intermediate values shown in comments
int transformed = transform(result); // => intermediate_value
System.out.println(transformed); // => final_output
}
}
```
**Key Takeaway**: 1-2 sentence summary highlighting the most important insight or pattern from this example.The brief explanation provides context. The code is heavily annotated with inline comments and // => output notation. The key takeaway distills the concept to its essence.
Mermaid diagrams appear when visual representation clarifies concept relationships - showing data flow, object hierarchies, or abstract structures. Not every example needs a diagram; they're used strategically to enhance understanding.
Learning Strategies
For Python/JavaScript Developers
You're used to dynamic typing and flexible syntax. Java will feel more structured and verbose:
- Static typing: Every variable has a declared type, caught at compile time
- Explicit OOP: Everything lives in classes, no standalone functions
- Checked exceptions: Must handle or declare exceptions explicitly
Focus on Examples 1-10 (types and classes) and Examples 19-20 (exception handling) to build static typing intuition.
For C/C++ Developers
You understand static typing and compilation. Java simplifies memory management:
- Garbage collection: No manual memory management, no pointers
- No header files: Single compilation unit per class
- Platform independence: Write once, run anywhere via JVM
Focus on Examples 70-90 (JVM internals) and Examples 46-55 (concurrency) to leverage your systems knowledge.
For Kotlin/Scala Developers
You know JVM semantics already. Java shows the foundation:
- Verbose but explicit: No type inference, everything declared
- No null safety: Must check nulls manually (or use Optional)
- Traditional OOP: No data classes, extension functions, or coroutines
Focus on Examples 65-90 (advanced features and JVM internals) to see modern Java capabilities.
Code-First Philosophy
This tutorial prioritizes working code over theoretical discussion:
- No lengthy prose: Concepts are demonstrated, not explained at length
- Runnable examples: Every example compiles and runs in JShell or as standalone classes
- Learn by doing: Understanding comes from running and modifying code
- Pattern recognition: See the same patterns in different contexts across 90 examples
If you prefer narrative explanations. By-example learning works best when you learn through experimentation.
Ready to Start?
Jump into the beginner examples to start learning Java through code:
- Beginner Examples (1-33) - Basic syntax, OOP fundamentals, collections, control flow
- Intermediate Examples (34-64) - Advanced OOP, generics, functional programming, concurrency
- Advanced Examples (65-90) - JVM internals, design patterns, modern Java features
Each example is self-contained and runnable. Start with Example 1, or jump to topics that interest you most.
Examples by Level
Beginner (Examples 1–33)
- Example 1: Hello World and JVM Compilation
- Example 2: Variables and Type System
- Example 3: Basic Input/Output with Scanner
- Example 4: Control Flow - If/Else and Switch
- Example 5: For Loop Basics
- Example 6: While and Do-While Loops
- Example 7: Enhanced For Loop (For-Each)
- Example 8: Array Basics
- Example 9: Array Utilities
- Example 10: Classes and Objects
- Example 11: Inheritance and Polymorphism
- Example 12: Interfaces and Abstraction
- Example 13: ArrayList - Dynamic Arrays
- Example 14: HashMap - Key-Value Mappings
- Example 15: HashSet - Unique Collections
- Example 16: Control Flow - Ternary and Operators
- Example 17: Enhanced Loops and Iterators
- Example 18: Methods and Parameter Passing
- Example 19: Exception Handling - Try/Catch/Finally
- Example 20: String Manipulation - Common Operations
- Example 21: StringBuilder - Efficient String Construction
- Example 22: Generics - Type-Safe Collections
- Example 23: Varargs - Variable-Length Arguments
- Example 24: Autoboxing and Wrapper Classes
- Example 25: Static Members and Initialization
- Example 26: Access Modifiers and Encapsulation
- Example 27: Packages and Imports
- Example 28: Enums - Type-Safe Constants
- Example 29: File I/O - Reading and Writing Files
- Example 30: Lambda Expressions and Functional Interfaces
- Example 31: Streams API - Functional Collection Processing
- Example 32: Optional - Null-Safe Value Containers
- Example 33: Date and Time API - Modern Temporal Types
Intermediate (Examples 34–64)
- Example 34: Abstract Classes and Template Method Pattern
- Example 35: Composition Over Inheritance
- Example 36: Nested and Inner Classes
- Example 37: Reflection API - Runtime Introspection
- Example 38: Annotations and Custom Metadata
- Example 39: Generic Methods and Bounded Type Parameters
- Example 40: Wildcards and Type Variance
- Example 41: ArrayList vs LinkedList Performance
- Example 42: HashSet vs TreeSet for Unique Collections
- Example 43: HashMap vs TreeMap and Collections Utilities
- Example 44: Concurrent Collections for Thread Safety
- Example 45: Stream Pipeline Optimization
- Example 46: Collectors and Stream Reduction
- Example 47: Method References and Function Composition
- Example 48: NIO.2 File Operations and Path API
- Example 49: Thread Basics and Runnable
- Example 50: Synchronization and Thread Safety
- Example 51: ExecutorService and Thread Pools
- Example 52: CompletableFuture for Async Programming
- Example 53: Records for Immutable Data
- Example 54: Sealed Classes for Closed Hierarchies
- Example 55: Pattern Matching for Switch
- Example 56: Optional for Null Safety
- Example 57: Stream API Collectors
- Example 58: Text Blocks for Multi-Line Strings
- Example 59: Local Variable Type Inference (var)
- Example 60: Try-With-Resources for Resource Management
- Example 61: Builder Pattern for Complex Objects
- Example 62: Immutability Patterns with Records
- Example 63: Try-With-Resources Automatic Cleanup
- Example 64: Custom Result Type for Functional Error Handling
Advanced (Examples 65–90)
- Example 65: Concurrent Collections
- Example 66: Atomic Variables
- Example 67: CountDownLatch and CyclicBarrier
- Example 68: Fork/Join Framework
- Example 69: Annotations and Reflection
- Example 70: Enums with Behavior
- Example 71: Sealed Classes and Pattern Matching
- Example 72: Module Basics (JPMS)
- Example 73: Module Visibility and JLink Custom Runtimes
- Example 74: var and Type Inference
- Example 75: Garbage Collection Basics
- Example 76: Memory Management and Reference Types
- Example 77: Performance Monitoring and Profiling
- Example 78: Common Performance Patterns
- Example 79: Connection Pool Factory Pattern
- Example 80: Strategy, Observer, Decorator
- Example 81: Dependency Injection Basics
- Example 82: Immutability Patterns
- Example 83: Virtual Threads (Project Loom, Java 21+)
- Example 84: Modern Java Best Practices
- Example 85: JVM Memory Model and Regions
- Example 86: Garbage Collection with G1GC
- Example 87: Ultra-Low Latency with ZGC
- Example 88: JVM Profiling with Java Flight Recorder (JFR)
- Example 89: CompletableFuture Advanced Patterns
- Example 90: Custom Annotations with Retention Policies
Last updated January 1, 2026