0

[Java Backend Zero to Hello] BÀI 2.11: JAVA 9-17 FEATURES

Java Backend Zero to Hello

📚 Bài viết thuộc series Java Backend Zero to Hello 📌 Phần: Phase 2: Java Core Nâng Cao | Bài 26/86


BÀI 2.11: JAVA 9-17 FEATURES

Mục tiêu

  • Nắm các tính năng mới từ Java 9 đến 17
  • Sử dụng var, record, sealed class
  • Áp dụng vào code thực tế

1. TỔNG QUAN CÁC VERSION

Version Năm Tính năng nổi bật
Java 8 2014 Lambda, Stream, Optional
Java 9 2017 Module, Collection factory, private interface method
Java 10 2018 var
Java 11 2018 LTS, HTTP Client, String methods
Java 14 2020 record, switch expression
Java 15 2020 sealed (preview), text block
Java 16 2021 record, sealed chính thức
Java 17 2021 LTS, sealed chính thức

2. VAR (Java 10+)

Khai báo biến với kiểu được suy luận từ giá trị khởi tạo.

// Trước
String name = "An";
List<Integer> numbers = new ArrayList<Integer>();

// Sau
var name = "An";                    // String
var numbers = new ArrayList<Integer>();  // ArrayList<Integer>
var stream = numbers.stream();      // Stream<Integer>

Quy tắc

  • Phải khởi tạo ngay khi khai báo
  • Không thể khai báo mà không gán: var x; ❌
  • Không thể dùng cho field của class
  • Không thể dùng cho parameter
// ❌ Không hợp lệ
var x;                    // Không khởi tạo
var y = null;             // Không suy luận được kiểu
var arr = {1, 2, 3};      // Không hợp lệ

// ✅ Hợp lệ
var list = new ArrayList<String>();
var result = computeSomething();

3. RECORD (Java 14+)

Class bất biến (immutable) - tự động sinh constructor, getter, equals, hashCode, toString.

3.1 Khai báo

// Trước - rất dài
public class User {
    private final String name;
    private final int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }

    @Override
    public boolean equals(Object o) { /* ... */ }

    @Override
    public int hashCode() { /* ... */ }

    @Override
    public String toString() { /* ... */ }
}

// Sau - rất ngắn
public record User(String name, int age) { }

3.2 Sử dụng

User user = new User("An", 25);
String name = user.name();  // "An" - không phải getName()
int age = user.age();       // 25

System.out.println(user);   // User[name=An, age=25]

3.3 Thêm method

public record User(String name, int age) {
    // Compact constructor - validate
    public User {
        if (age < 0) {
            throw new IllegalArgumentException("Age must be >= 0");
        }
    }

    // Method thường
    public boolean isAdult() {
        return age >= 18;
    }

    // Static method
    public static User createDefault() {
        return new User("Unknown", 0);
    }
}

3.4 Khi nào dùng Record

  • ✅ DTO, Value Object
  • ✅ Response từ API
  • ✅ Data transfer giữa các layer
  • ❌ Entity JPA (cần mutable)
  • ❌ Class có logic phức tạp

4. SEALED CLASS (Java 17+)

Giới hạn class nào được kế thừa.

4.1 Khai báo

public sealed class Shape
    permits Circle, Rectangle, Triangle {

    public abstract double area();
}

public final class Circle extends Shape {
    private final double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

public final class Rectangle extends Shape {
    private final double width, height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double area() {
        return width * height;
    }
}

public final class Triangle extends Shape {
    private final double base, height;

    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }

    @Override
    public double area() {
        return 0.5 * base * height;
    }
}

4.2 Các từ khóa cho class con

  • final - Không cho kế thừa tiếp
  • sealed - Cho phép kế thừa có giới hạn
  • non-sealed - Cho phép kế thừa tự do

4.3 Pattern Matching với Sealed

public String describe(Shape shape) {
    return switch (shape) {
        case Circle c -> "Hình tròn bán kính " + c.radius();
        case Rectangle r -> "Hình chữ nhật " + r.width() + "x" + r.height();
        case Triangle t -> "Tam giác";
    };
}

5. SWITCH EXPRESSION (Java 14+)

Switch trả về giá trị.

// Cũ
String dayName;
switch (day) {
    case 1: dayName = "Thứ 2"; break;
    case 2: dayName = "Thứ 3"; break;
    default: dayName = "Không rõ";
}

// Mới
String dayName = switch (day) {
    case 1 -> "Thứ 2";
    case 2 -> "Thứ 3";
    case 3, 4, 5 -> "Giữa tuần";
    case 6, 7 -> "Cuối tuần";
    default -> "Không rõ";
};

Với yield

String result = switch (value) {
    case 1 -> "Một";
    case 2 -> {
        System.out.println("Hai");
        yield "Hai";
    }
    default -> "Khác";
};

6. TEXT BLOCK (Java 13+)

Chuỗi nhiều dòng.

String html = """
        <html>
            <body>
                <h1>Hello</h1>
            </body>
        </html>
        """;

String json = """
        {
            "name": "Java",
            "version": 17
        }
        """;

7. PATTERN MATCHING (Java 16+)

7.1 instanceof

// Cũ
if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.length());
}

// Mới
if (obj instanceof String s) {
    System.out.println(s.length());
}

7.2 switch với Pattern (Preview)

String formatted = switch (obj) {
    case Integer i -> "Integer: " + i;
    case Long l -> "Long: " + l;
    case Double d -> "Double: " + d;
    case String s -> "String: " + s;
    case null -> "Null";
    default -> "Unknown";
};

8. CÁC METHOD MỚI CỦA STRING

// Java 11+
"  Hello  ".strip();           // "Hello" - Unicode whitespace
"  Hello  ".stripLeading();    // "Hello  "
"  Hello  ".stripTrailing();   // "  Hello"
"".isEmpty();                  // true
"   ".isBlank();               // true
"Hello\nWorld".lines().count(); // 2
"Hello".repeat(3);             // "HelloHelloHello"

9. COLLECTION FACTORY METHODS (Java 9+)

// Tạo collection immutable ngắn gọn
List<String> list = List.of("A", "B", "C");
Set<Integer> set = Set.of(1, 2, 3);
Map<String, Integer> map = Map.of("A", 1, "B", 2);

// Map.ofEntries cho nhiều entry
Map<String, Integer> map2 = Map.ofEntries(
    Map.entry("A", 1),
    Map.entry("B", 2),
    Map.entry("C", 3)
);

10. HTTP CLIENT (Java 11+)

import java.net.http.*;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/users"))
    .header("Content-Type", "application/json")
    .GET()
    .build();

HttpResponse<String> response = client.send(
    request, HttpResponse.BodyHandlers.ofString()
);

System.out.println(response.body());

11. BÀI TẬP THỰC HÀNH

Bài 1: DTO với Record

public record UserDTO(
    Long id,
    String name,
    String email,
    LocalDateTime createdAt
) {}

public record CreateUserRequest(
    @NotBlank String name,
    @Email String email,
    @Min(0) int age
) {}

Bài 2: Sealed Class cho Response

public sealed interface ApiResponse<T>
    permits Success, Error {

    record Success<T>(T data) implements ApiResponse<T> {}
    record Error<T>(String message, int code) implements ApiResponse<T> {}
}

public String handle(ApiResponse<?> response) {
    return switch (response) {
        case ApiResponse.Success<?> s -> "Data: " + s.data();
        case ApiResponse.Error<?> e -> "Error: " + e.message();
    };
}

Bài 3: HTTP Client

public String fetchData(String url) throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(url))
        .build();
    HttpResponse<String> response = client.send(
        request, HttpResponse.BodyHandlers.ofString()
    );
    return response.body();
}

12. TÓM TẮT

Tính năng Version Mô tả
var 10 Suy luận kiểu local
record 14 Class immutable ngắn gọn
sealed 17 Giới hạn kế thừa
Switch expression 14 Switch trả về giá trị
Text block 13 Chuỗi nhiều dòng
Pattern matching 16 instanceof + switch
HTTP Client 11 Gọi HTTP hiện đại
Collection factory 9 List.of(), Set.of()

Bài tiếp theo: 2.12 Bài tập cuối Phase 2


🧭 Điều Hướng Series

⬅️ Bài trước: BÀI 2.10: ENUM & NESTED CLASS

📋 Lộ trình tổng quan: Xem Toàn Bộ Series

➡️ Bài tiếp theo: BÀI 2.12: BÀI TẬP CUỐI PHASE 2


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí