# Java 17 Features Every Senior Developer Should Know - Part 6: Syntax Cheat Sheet & Reference Guide

**Complete Reference for Desktop** | Print-friendly version for desk reference

This is Part 6 (final) of "Java 17 Features Every Senior Developer Should Know" - a comprehensive reference covering syntax, usage patterns, feature interactions, and migration strategies for all 6 features covered in Parts 1-5. Perfect for printing and keeping at your desk as you work with modern Java code.

## How to Use This Series

**First time learning Java 17 features?**

* Read [Part 1: var Keyword](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-1-introduction-and-var-keyword) → [Part 2: Records](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-2-records) → [Part 3: Sealed Classes](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-3-sealed-classes) → [Part 4: Pattern Matching](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-4-pattern-matching-and-switch-expressions) → [Part 5: Text Blocks](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-5-text-blocks)
    
* Each part includes practical examples and best practices
    
* Estimated reading time: 1-2 hours total
    

**Need a quick reference?**

* Use the Quick Reference Cards below (this page)
    
* Each section provides syntax, examples, and use cases at a glance
    
* Links to full parts for detailed explanations
    

**Looking for specific feature?**

* Use the Table of Contents below to jump to any feature
    
* Each Quick Reference Card links back to its full part
    

**Want to understand feature interactions?**

* See full articles for detailed explanations and real-world patterns
    

**Planning a migration?**

* See full articles for phased migration strategy and compatibility notes
    

---

## Series Overview & Timeline

This series covers **6 major Java features spanning Java 10-17**, representing over 20 years of language evolution:

| Part | Feature | Release | JEP |
| --- | --- | --- | --- |
| 1 | **var** - Local variable type inference | Java 10 | 286 |
| 2 | **Records** - Immutable data carriers | Java 16 | 395 |
| 3 | **Sealed Classes** - Controlled inheritance | Java 17 | 409 |
| 4 | **Pattern Matching** - Type check + cast | Java 16 | 394 |
| 5 | **Switch Expressions** - Returns values | Java 14 | 361 |
| 6 | **Text Blocks** - Multi-line strings | Java 15 | 378 |

**Why These Features Matter:**

* **Part 1-2**: Reduce boilerplate (less code to write)
    
* **Part 3-4**: Increase safety (compiler catches more errors)
    
* **Part 5-6**: Improve readability (code matches intent)
    

---

## Feature Comparison Matrix

### Decision At-a-Glance

| Challenge | Solution | When | Avoid |
| --- | --- | --- | --- |
| Long generic types | `var` | Type obvious from right side | Type unclear from context |
| Immutable data classes | `Records` | DTOs, value objects | Mutable data, need inheritance |
| Controlled inheritance | `Sealed classes` | Fixed type hierarchies | Open-for-extension APIs |
| Type checking + casting | `Pattern matching` | Checking types with immediate use | Polymorphism is better choice |
| Returning from switch | `Switch expressions` | Enum mapping, value computation | Simple if-else, need fall-through |
| Multi-line strings | `Text blocks` | JSON, SQL, HTML, XML | Single line strings |

### Feature Dependencies

```plaintext
var (Java 10)
    ↓ (enables clean declaration of)
Records (Java 16)
    ↓ (work well with)
Sealed Classes (Java 17)
    ↓ (enables exhaustive checking with)
Pattern Matching (Java 16)
    ↓ (used in)
Switch Expressions (Java 14)
    ↓ (format data with)
Text Blocks (Java 15)
```

---

## Quick Reference Cards

### var Keyword (Java 10)

**JEP 286** | Local variable type inference

📖 **See also**: [Part 1: Introduction & var Keyword](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-1-introduction-and-var-keyword) - Full feature deep dive with examples and pitfalls

**Syntax**

```java
var name = expression;
```

**✅ Use When**

* Type is obvious from right side: `var user = new User()`
    
* Long generic types: `var map = new HashMap<String, List<Employee>>()`
    
* Stream chains: `var filtered = list.stream().filter(...)`
    
* For-loops: `for (var item : items)`
    

**❌ Don't Use When**

* Type isn't clear: `var data = fetchData()` (what type?)
    
* Need supertype: `List<String> list = new ArrayList<>()` (flexibility)
    
* Fields, parameters, return types (not allowed)
    
* Lambda/method reference alone: `var c = String::length` (error)
    

**Examples**

```java
// ✅ Good
var message = "Hello";
var count = 42;
var users = List.of("Alice", "Bob");
var map = new HashMap<String, Integer>();

// ❌ Bad
var x = getData();           // unclear type
var y = null;                // error: cannot infer
var list = new ArrayList<>(); // error: need type args
```

**Quick Rules**

* Compile-time type inference (NOT dynamic typing)
    
* Local variables only
    
* Must have initializer
    
* Type never changes
    

---

## Records (Java 16)

**JEP 395** | Immutable data carriers

📖 **See also**: [Part 2: Records](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-2-records) - Full feature deep dive with examples and best practices

**Syntax**

```java
record Name(Type1 field1, Type2 field2) {
    // optional: custom methods, validation
}
```

**✅ Use When**

* Data Transfer Objects (DTOs)
    
* Value objects (Point, Money, Range)
    
* Configuration objects
    
* API request/response models
    
* Return values from methods (multiple values)
    

**❌ Don't Use When**

* Need mutability
    
* Need inheritance (records are final)
    
* Want to hide internal structure
    
* Need JavaBeans getters (use `field()` not `getField()`)
    
* Complex lazy initialization
    

**Examples**

```java
// Basic record
record Point(int x, int y) {}

// With validation (compact constructor)
record Range(int start, int end) {
    public Range {
        if (start > end) throw new IllegalArgumentException();
    }
}

// With custom methods
record Person(String name, int age) {
    public boolean isAdult() { return age >= 18; }
    public Person withAge(int newAge) { return new Person(name, newAge); }
}

// Generic record
record Pair<T, U>(T first, U second) {}

// Implementing interface
record Circle(double radius) implements Shape {
    @Override
    public double area() { return Math.PI * radius * radius; }
}
```

**What You Get Automatically**

* Constructor: `public Point(int x, int y)`
    
* Accessors: `p.x()`, `p.y()` (NOT getX(), getY())
    
* `equals()`, `hashCode()`, `toString()`
    
* Fields are `private final`
    
* Class is `final`
    

**Quick Rules**

* Immutable by default
    
* All fields final
    
* Cannot extend other classes
    
* Can implement interfaces
    
* Defensive copying needed for mutable components
    

---

## Sealed Classes (Java 17)

**JEP 409** | Controlled inheritance

📖 **See also**: [Part 3: Sealed Classes](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-3-sealed-classes) - Design patterns and hierarchy control explained

**Syntax**

```java
sealed interface/class Name permits SubType1, SubType2 {
}

// Subtypes must be: final, sealed, or non-sealed
```

**✅ Use When**

* Closed type hierarchies (known subtypes only)
    
* Domain modeling with fixed alternatives
    
* Exhaustive pattern matching
    
* API design where you control all implementations
    

**❌ Don't Use When**

* Open for extension (third-party implementations)
    
* Plugin architectures
    
* Need unlimited subclassing
    

**Examples**

```java
// Sealed interface with records
sealed interface Shape permits Circle, Rectangle, Triangle {}

record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
record Triangle(double base, double height) implements Shape {}

// Sealed class hierarchy
sealed class Result<T> permits Success, Failure {}

final class Success<T> extends Result<T> {
    private final T value;
    // ...
}

final class Failure<T> extends Result<T> {
    private final String error;
    // ...
}

// With non-sealed for extension point
sealed interface Payment permits CreditCard, DebitCard, ExtensiblePayment {}
final class CreditCard implements Payment {}
final class DebitCard implements Payment {}
non-sealed interface ExtensiblePayment extends Payment {} // Open for extension
```

**Permitted Subtypes Must**

* Be in same module (or same package if unnamed module)
    
* Directly extend/implement the sealed type
    
* Be declared as: `final`, `sealed`, or `non-sealed`
    

**Quick Rules**

* Compiler knows all subtypes
    
* Enables exhaustive pattern matching
    
* Subtypes must be declared in permits clause
    
* Better than marker interfaces for closed sets
    

---

## Pattern Matching (Java 16)

**JEP 394** | Pattern matching for instanceof

📖 **See also**: [Part 4: Pattern Matching & Switch Expressions](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-4-pattern-matching-and-switch-expressions) - Type patterns and exhaustiveness checking

**Syntax**

```java
if (obj instanceof Type variableName) {
    // use variableName here
}
```

**✅ Use When**

* Type checking with immediate use
    
* Implementing `equals()` methods
    
* Polymorphic dispatch
    
* Guard conditions: `obj instanceof String s && s.length() > 5`
    

**❌ Don't Use When**

* Polymorphism would be better (add methods to types)
    
* Type checking indicates design smell
    
* Performance is absolutely critical
    

**Examples**

```java
// Basic pattern matching
if (obj instanceof String s) {
    System.out.println(s.toUpperCase());
}

// With guards
if (obj instanceof String s && s.length() > 0) {
    return s.toUpperCase();
}

// Simplified equals()
@Override
public boolean equals(Object obj) {
    return obj instanceof Point p && this.x == p.x && this.y == p.y;
}

// Type hierarchy
if (shape instanceof Circle c) {
    return Math.PI * c.radius() * c.radius();
} else if (shape instanceof Rectangle r) {
    return r.width() * r.height();
}
```

**Scope Rules**

```java
if (obj instanceof String s && s.length() > 5) {
    // 's' in scope here
}

if (!(obj instanceof String s)) {
    // 's' NOT in scope
} else {
    // 's' IS in scope here
}
```

**Quick Rules**

* Pattern variable scoped by flow analysis
    
* instanceof returns false for null (safe)
    
* No manual cast needed
    
* Combines type check + cast + assignment
    

---

## Switch Expressions (Java 14)

**JEP 361** | Switch as expression with arrow syntax

📖 **See also**: [Part 4: Pattern Matching & Switch Expressions](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-4-pattern-matching-and-switch-expressions) - Clean conditional logic with yield

**Syntax**

```java
// Arrow syntax (no fall-through)
var result = switch (value) {
    case LABEL1 -> expression1;
    case LABEL2, LABEL3 -> expression2;
    default -> expressionN;
};

// Multi-statement with yield
var result = switch (value) {
    case LABEL1 -> {
        // statements
        yield value1;
    }
};
```

**✅ Use When**

* Mapping enum values
    
* Returning values from branches
    
* Exhaustive enum matching (no default needed)
    
* Multi-way conditional logic
    

**❌ Don't Use When**

* Simple if-else would suffice
    
* Need fall-through (use colon syntax)
    
* Cases are complex and unrelated
    

**Examples**

```java
// Basic switch expression
String dayType = switch (day) {
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "Weekday";
    case SATURDAY, SUNDAY -> "Weekend";
};

// With yield
int result = switch (op) {
    case ADD -> {
        System.out.println("Adding");
        yield a + b;
    }
    case SUBTRACT -> {
        System.out.println("Subtracting");
        yield a - b;
    }
    default -> throw new IllegalArgumentException();
};

// Exhaustive enum (no default needed)
int days = switch (season) {
    case SPRING, SUMMER, FALL, WINTER -> 3;
};
```

**Quick Rules**

* Arrow `->` prevents fall-through
    
* Must be exhaustive (all cases or default)
    
* Use `yield` for multi-statement branches
    
* No `break` needed with arrows
    
* Can mix with pattern matching (future Java)
    

---

## Text Blocks (Java 15)

**JEP 378** | Multi-line string literals

📖 **See also**: [Part 5: Text Blocks](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-5-text-blocks) - Multi-line strings with security considerations

**Syntax**

```java
String text = """
    content here
    more content
    """;
```

**✅ Use When**

* Multi-line strings (JSON, SQL, HTML, XML)
    
* Embedded code snippets
    
* Long error messages
    
* Test fixtures
    

**❌ Don't Use When**

* Single-line strings
    
* Dynamically built strings
    
* Need platform-specific line endings
    

**Examples**

```java
// JSON
String json = """
    {
      "name": "Alice",
      "age": 30,
      "email": "alice@example.com"
    }""";

// SQL
String sql = """
    SELECT u.name, u.email, o.total
    FROM users u
    JOIN orders o ON u.id = o.user_id
    WHERE o.status = 'COMPLETED'
    ORDER BY o.created_at DESC""";

// With formatted()
String json = """
    {
      "name": "%s",
      "age": %d
    }""".formatted(name, age);

// Indentation control
String text = """
    Line 1
        Indented line 2
    Line 3
    """;  // Closing delimiter determines indent stripping

// Line continuation
String long = """
    This is a long line that \
    continues on the next line \
    in source code.
    """;

// Essential space
String trailing = """
    Line with space:\s
    """;
```

**Special Escapes**

* `\s` - Essential space (survives whitespace stripping)
    
* `\` - Line continuation (no newline inserted)
    
* Standard escapes work: `\n`, `\t`, `\"`, `\\`
    

**Quick Rules**

* Opening `"""` must be followed by newline
    
* Closing `"""` position determines indent
    
* All line endings normalized to `\n`
    
* Trailing whitespace auto-removed
    
* Common indent automatically stripped
    

---

**End of Series**

This concludes "Java 17 Features Every Senior Developer Should Know"

* **Part 1**: [var Keyword](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-1-introduction-and-var-keyword)
    
* **Part 2**: [Records](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-2-records)
    
* **Part 3**: [Sealed Classes](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-3-sealed-classes)
    
* **Part 4**: [Pattern Matching & Switch Expressions](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-4-pattern-matching-and-switch-expressions)
    
* **Part 5**: [Text Blocks](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-5-text-blocks)
    
* **Part 6**: Syntax Cheat Sheet (this document)
    

---

## Series Navigation

* **←** [**Part 5: Text Blocks**](https://blog.9mac.dev/java-17-features-every-senior-developer-should-know-part-5-text-blocks) - Multi-line string literals
    
* **←** [**Series Overview**](https://blog.9mac.dev/series/java-and-jvm) - Overview and series guide
