google-site-verification: google61fe8ba583a51912.html
Deconstruction Patterns in Java: Complete Guide

Explore Java's powerful deconstruction patterns including Records, Pattern Matching, and advanced destructuring techniques.

Table of Contents

  1. Record Deconstruction
  2. Pattern Matching with instanceof
  3. Switch Expression Patterns
  4. Custom Deconstruction Patterns
  5. Advanced Nesting Patterns
  6. Real-World Use Cases

Record Deconstruction

1. Basic Record Deconstruction

// Basic record definition public record Person(String name, int age, String email) { // Compact constructor with validation public Person { if (age < 0) { throw new IllegalArgumentException("Age cannot be negative"); } if (email != null && !email.contains("@")) { throw new IllegalArgumentException("Invalid email format"); } } // Static factory method public static Person of(String name, int age) { return new Person(name, age, null); } } // Deconstruction examples public class RecordDeconstruction { public static void main(String[] args) { // Create record instance Person person = new Person("Alice", 30, "[email protected]"); // Traditional accessors String name = person.name(); int age = person.age(); String email = person.email(); // Deconstruction in Java 16+ (conceptual - not actual syntax) // This demonstrates the concept that will be available in future versions System.out.println("Name: " + name + ", Age: " + age + ", Email: " + email); } // Method that demonstrates deconstruction concept public static void processPerson(Person person) { // Imagine future Java version supporting this: // Person(String name, int age, String email) = person; // Current approach - using accessors String name = person.name(); int age = person.age(); String email = person.email(); System.out.printf("Processing %s (%d years old) - %s%n", name, age, email); } }

2. Advanced Record Patterns

// Complex record with nested records public record Address(String street, String city, String zipCode, String country) { public Address { if (street == null || street.isBlank()) { throw new IllegalArgumentException("Street cannot be empty"); } } public String format() { return String.format("%s, %s %s, %s", street, city, zipCode, country); } } public record Employee( String id, Person person, Address address, String department, double salary ) { public Employee { if (salary < 0) { throw new IllegalArgumentException("Salary cannot be negative"); } } public boolean isRemote() { return address.city().equals("REMOTE"); } } // Record pattern matching examples public class AdvancedRecordPatterns { // Traditional approach to extracting data public static void printEmployeeInfoTraditional(Employee employee) { Person person = employee.person(); Address address = employee.address(); String name = person.name(); String city = address.city(); System.out.printf("Employee %s works in %s%n", name, city); } // Using method to simulate pattern matching public static void extractEmployeeData(Employee employee) { // Simulating what pattern matching might look like String id = employee.id(); Person person = employee.person(); Address address = employee.address(); String department = employee.department(); double salary = employee.salary(); // Process extracted data if (salary > 100000) { System.out.printf("High earner: %s in %s%n", person.name(), department); } } // Process multiple records public static void processEmployees(List<Employee> employees) { for (Employee emp : employees) { // Extract nested data String empName = emp.person().name(); String empCity = emp.address().city(); double empSalary = emp.salary(); System.out.printf("%s in %s earns $%.2f%n", empName, empCity, empSalary); } } }

Pattern Matching with instanceof

3. Type Pattern Matching

// Hierarchy of shapes public sealed interface Shape permits Circle, Rectangle, Triangle, CompositeShape { double area(); double perimeter(); } public record Circle(double radius) implements Shape { public Circle { if (radius <= 0) { throw new IllegalArgumentException("Radius must be positive"); } } @Override public double area() { return Math.PI * radius * radius; } @Override public double perimeter() { return 2 * Math.PI * radius; } } public record Rectangle(double width, double height) implements Shape { public Rectangle { if (width <= 0 || height <= 0) { throw new IllegalArgumentException("Dimensions must be positive"); } } @Override public double area() { return width * height; } @Override public double perimeter() { return 2 * (width + height); } public boolean isSquare() { return width == height; } } public record Triangle(double side1, double side2, double side3) implements Shape { public Triangle { if (side1 <= 0 || side2 <= 0 || side3 <= 0) { throw new IllegalArgumentException("Sides must be positive"); } // Triangle inequality validation if (side1 + side2 <= side3 || side1 + side3 <= side2 || side2 + side3 <= side1) { throw new IllegalArgumentException("Invalid triangle sides"); } } @Override public double area() { // Heron's formula double s = perimeter() / 2; return Math.sqrt(s * (s - side1) * (s - side2) * (s - side3)); } @Override public double perimeter() { return side1 + side2 + side3; } } public record CompositeShape(String name, List<Shape> components) implements Shape { public CompositeShape { if (components == null || components.isEmpty()) { throw new IllegalArgumentException("Components cannot be empty"); } } @Override public double area() { return components.stream() .mapToDouble(Shape::area) .sum(); } @Override public double perimeter() { // For composite shapes, perimeter might not be well-defined return components.stream() .mapToDouble(Shape::perimeter) .sum(); } } // Pattern matching with instanceof public class InstanceOfPatternMatching { // Traditional instanceof with casting public static String describeShapeTraditional(Shape shape) { if (shape instanceof Circle) { Circle circle = (Circle) shape; return String.format("Circle with radius %.2f (area: %.2f)", circle.radius(), circle.area()); } else if (shape instanceof Rectangle) { Rectangle rect = (Rectangle) shape; return String.format("Rectangle %.2f x %.2f (area: %.2f)", rect.width(), rect.height(), rect.area()); } else if (shape instanceof Triangle) { Triangle tri = (Triangle) shape; return String.format("Triangle with sides %.2f, %.2f, %.2f", tri.side1(), tri.side2(), tri.side3()); } else { return "Unknown shape"; } } // Modern pattern matching with instanceof (Java 16+) public static String describeShapeModern(Shape shape) { if (shape instanceof Circle circle) { return String.format("Circle with radius %.2f (area: %.2f)", circle.radius(), circle.area()); } else if (shape instanceof Rectangle rect) { String type = rect.isSquare() ? "Square" : "Rectangle"; return String.format("%s %.2f x %.2f (area: %.2f)", type, rect.width(), rect.height(), rect.area()); } else if (shape instanceof Triangle tri) { return String.format("Triangle with sides %.2f, %.2f, %.2f (perimeter: %.2f)", tri.side1(), tri.side2(), tri.side3(), tri.perimeter()); } else if (shape instanceof CompositeShape comp) { return String.format("Composite shape '%s' with %d components (total area: %.2f)", comp.name(), comp.components().size(), comp.area()); } else { return "Unknown shape"; } } // Pattern matching with additional conditions public static String analyzeShape(Shape shape) { if (shape instanceof Circle circle && circle.radius() > 10) { return "Large circle: " + circle.radius(); } else if (shape instanceof Rectangle rect && rect.isSquare()) { return "Square with side: " + rect.width(); } else if (shape instanceof Triangle tri) { if (tri.side1() == tri.side2() && tri.side2() == tri.side3()) { return "Equilateral triangle"; } else if (tri.side1() == tri.side2() || tri.side1() == tri.side3() || tri.side2() == tri.side3()) { return "Isosceles triangle"; } else { return "Scalene triangle"; } } else { return "Other shape"; } } // Processing collections with pattern matching public static void processShapes(List<Shape> shapes) { for (Shape shape : shapes) { if (shape instanceof Circle circle) { System.out.printf("Processing circle (r=%.2f)%n", circle.radius()); } else if (shape instanceof Rectangle rect) { System.out.printf("Processing rectangle (%.2fx%.2f)%n", rect.width(), rect.height()); } // Additional processing... } } }

Switch Expression Patterns

4. Enhanced Switch Patterns

// Domain models for different types of events public sealed interface Event permits UserEvent, SystemEvent, AuditEvent, ErrorEvent { String id(); Instant timestamp(); String source(); } public record UserEvent( String id, Instant timestamp, String source, String userId, String action, Map<String, Object> metadata ) implements Event {} public record SystemEvent( String id, Instant timestamp, String source, String component, String operation, Duration duration ) implements Event {} public record AuditEvent( String id, Instant timestamp, String source, String auditor, String target, String action, boolean success ) implements Event {} public record ErrorEvent( String id, Instant timestamp, String source, String errorType, String message, String stackTrace, Severity severity ) implements Event { public enum Severity { LOW, MEDIUM, HIGH, CRITICAL } } // Switch pattern matching examples public class SwitchPatternMatching { // Traditional switch statement public static String processEventTraditional(Event event) { if (event instanceof UserEvent) { UserEvent userEvent = (UserEvent) event; return "User action: " + userEvent.action(); } else if (event instanceof SystemEvent) { SystemEvent sysEvent = (SystemEvent) event; return "System operation: " + sysEvent.operation(); } else if (event instanceof AuditEvent) { AuditEvent auditEvent = (AuditEvent) event; return "Audit: " + auditEvent.action() + " - " + (auditEvent.success() ? "SUCCESS" : "FAILED"); } else if (event instanceof ErrorEvent) { ErrorEvent errorEvent = (ErrorEvent) event; return "Error: " + errorEvent.message(); } else { return "Unknown event"; } } // Modern switch expression with pattern matching (Java 21+ preview) public static String processEventModern(Event event) { return switch (event) { case UserEvent userEvent -> String.format("User %s performed: %s", userEvent.userId(), userEvent.action()); case SystemEvent sysEvent when sysEvent.duration().toMinutes() > 5 -> String.format("Long system operation: %s took %d minutes", sysEvent.operation(), sysEvent.duration().toMinutes()); case SystemEvent sysEvent -> String.format("System operation: %s completed", sysEvent.operation()); case AuditEvent auditEvent when !auditEvent.success() -> String.format("AUDIT FAILURE: %s on %s", auditEvent.action(), auditEvent.target()); case AuditEvent auditEvent -> String.format("Audit: %s completed successfully", auditEvent.action()); case ErrorEvent errorEvent when errorEvent.severity() == ErrorEvent.Severity.CRITICAL -> String.format("CRITICAL ERROR: %s - %s", errorEvent.errorType(), errorEvent.message()); case ErrorEvent errorEvent -> String.format("Error [%s]: %s", errorEvent.severity(), errorEvent.message()); default -> "Unknown event type"; }; } // Complex pattern matching with nested extraction public static void analyzeEvents(List<Event> events) { for (Event event : events) { String analysis = switch (event) { case UserEvent(var id, var timestamp, var source, var userId, var action, var metadata) -> { if (action.equals("LOGIN")) { yield String.format("User %s logged in from %s", userId, source); } else if (action.equals("LOGOUT")) { yield String.format("User %s logged out", userId); } else { yield String.format("User %s performed %s", userId, action); } } case SystemEvent(var id, var timestamp, var source, var component, var operation, var duration) when duration.toSeconds() > 60 -> { yield String.format("Slow system operation: %s.%s took %d seconds", component, operation, duration.toSeconds()); } case ErrorEvent(var id, var timestamp, var source, var errorType, var message, var stackTrace, var severity) when severity == ErrorEvent.Severity.HIGH -> { yield String.format("High severity error in %s: %s", source, message); } case null -> "Null event encountered"; default -> "Event type: " + event.getClass().getSimpleName(); }; System.out.println(analysis); } } // Pattern matching with guards and complex conditions public static String categorizeEvent(Event event) { return switch (event) { case UserEvent user when user.action().contains("DELETE") -> "DESTRUCTIVE_USER_ACTION"; case UserEvent user when user.action().contains("CREATE") -> "CREATIVE_USER_ACTION"; case SystemEvent sys when sys.duration().toMillis() > 5000 -> "LONG_RUNNING_SYSTEM_OPERATION"; case SystemEvent sys when sys.component().equals("DATABASE") -> "DATABASE_OPERATION"; case AuditEvent audit when !audit.success() -> "AUDIT_FAILURE"; case ErrorEvent error when error.severity() == ErrorEvent.Severity.CRITICAL -> "CRITICAL_FAILURE"; case ErrorEvent error when error.message().contains("timeout") -> "TIMEOUT_ERROR"; default -> "STANDARD_EVENT"; }; } }

Custom Deconstruction Patterns

5. Creating Custom Destructuring Methods

// Traditional class with custom deconstruction public class ComplexNumber { private final double real; private final double imaginary; public ComplexNumber(double real, double imaginary) { this.real = real; this.imaginary = imaginary; } // Traditional getters public double getReal() { return real; } public double getImaginary() { return imaginary; } // Custom deconstruction method public ComplexParts deconstruct() { return new ComplexParts(real, imaginary); } // Static factory method for construction public static ComplexNumber of(double real, double imaginary) { return new ComplexNumber(real, imaginary); } // Record for deconstructed parts public record ComplexParts(double real, double imaginary) { public ComplexNumber toComplexNumber() { return new ComplexNumber(real, imaginary); } } @Override public String toString() { return String.format("%.2f + %.2fi", real, imaginary); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ComplexNumber that)) return false; return Double.compare(that.real, real) == 0 && Double.compare(that.imaginary, imaginary) == 0; } @Override public int hashCode() { return Objects.hash(real, imaginary); } } // Custom container with deconstruction support public class Pair<A, B> { private final A first; private final B second; public Pair(A first, B second) { this.first = first; this.second = second; } public A first() { return first; } public B second() { return second; } // Deconstruction method public Object[] deconstruct() { return new Object[]{first, second}; } // Pattern matching support method public boolean matches(Class<A> firstType, Class<B> secondType) { return firstType.isInstance(first) && secondType.isInstance(second); } @Override public String toString() { return String.format("Pair[%s, %s]", first, second); } // Static factory public static <A, B> Pair<A, B> of(A first, B second) { return new Pair<>(first, second); } } // Custom deconstruction examples public class CustomDeconstruction { public static void processComplexNumber(ComplexNumber cn) { // Traditional approach double real = cn.getReal(); double imaginary = cn.getImaginary(); // Using custom deconstruction ComplexNumber.ComplexParts parts = cn.deconstruct(); double r = parts.real(); double i = parts.imaginary(); System.out.printf("Complex number: %.2f + %.2fi%n", r, i); } public static void processPair(Pair<?, ?> pair) { Object[] components = pair.deconstruct(); Object first = components[0]; Object second = components[1]; System.out.printf("Pair contains: %s and %s%n", first, second); // Type-safe processing with pattern matching simulation if (pair.matches(String.class, Integer.class)) { @SuppressWarnings("unchecked") Pair<String, Integer> stringIntPair = (Pair<String, Integer>) pair; processStringIntPair(stringIntPair); } } private static void processStringIntPair(Pair<String, Integer> pair) { String name = pair.first(); Integer value = pair.second(); System.out.printf("String-Integer pair: %s -> %d%n", name, value); } // Advanced deconstruction with multiple return values public static class DataPoint { private final String label; private final double[] values; private final Map<String, Object> metadata; public DataPoint(String label, double[] values, Map<String, Object> metadata) { this.label = label; this.values = values.clone(); // Defensive copy this.metadata = new HashMap<>(metadata); } // Multiple deconstruction options public BasicComponents deconstructBasic() { return new BasicComponents(label, values.length); } public FullComponents deconstructFull() { return new FullComponents(label, values, metadata); } public record BasicComponents(String label, int valueCount) {} public record FullComponents(String label, double[] values, Map<String, Object> metadata) {} public String label() { return label; } public double[] values() { return values.clone(); } // Defensive copy public Map<String, Object> metadata() { return new HashMap<>(metadata); } } }

Advanced Nesting Patterns

6. Complex Nested Pattern Matching

// Complex domain model for e-commerce public record Customer( String id, String name, Address address, List<Order> orders, CustomerPreferences preferences ) { public Customer { if (orders == null) orders = new ArrayList<>(); if (preferences == null) preferences = new CustomerPreferences(); } public boolean hasOrders() { return !orders.isEmpty(); } } public record CustomerPreferences( boolean emailNotifications, boolean smsNotifications, String currency, String language, List<String> favoriteCategories ) { public CustomerPreferences { if (favoriteCategories == null) favoriteCategories = new ArrayList<>(); if (currency == null) currency = "USD"; if (language == null) language = "en"; } } public record Order( String orderId, Instant orderDate, List<OrderItem> items, OrderStatus status, PaymentInfo payment, ShippingInfo shipping ) { public double totalAmount() { return items.stream() .mapToDouble(item -> item.price() * item.quantity()) .sum(); } public boolean isShippable() { return status == OrderStatus.CONFIRMED || status == OrderStatus.PROCESSING; } } public record OrderItem( String productId, String productName, int quantity, double price, Map<String, String> attributes ) { public double subtotal() { return price * quantity; } } public enum OrderStatus { PENDING, CONFIRMED, PROCESSING, SHIPPED, DELIVERED, CANCELLED } public record PaymentInfo( String paymentMethod, String transactionId, boolean paid, Instant paymentDate ) {} public record ShippingInfo( Address shippingAddress, String carrier, String trackingNumber, Instant estimatedDelivery ) {} // Advanced nested pattern matching public class NestedPatternMatching { // Process customer with nested pattern matching simulation public static void analyzeCustomer(Customer customer) { // Extract nested data String customerName = customer.name(); Address address = customer.address(); List<Order> orders = customer.orders(); CustomerPreferences prefs = customer.preferences(); // Process address String city = address.city(); String country = address.country(); // Process preferences boolean wantsEmails = prefs.emailNotifications(); String preferredCurrency = prefs.currency(); System.out.printf("Customer %s in %s, %s%n", customerName, city, country); System.out.printf("Preferences: email=%s, currency=%s%n", wantsEmails, preferredCurrency); // Process orders with nested data for (Order order : orders) { processOrder(order); } } private static void processOrder(Order order) { String orderId = order.orderId(); OrderStatus status = order.status(); double total = order.totalAmount(); List<OrderItem> items = order.items(); PaymentInfo payment = order.payment(); ShippingInfo shipping = order.shipping(); System.out.printf("Order %s: %s, Total: $%.2f%n", orderId, status, total); // Process payment info if (payment.paid()) { System.out.printf(" Paid via %s on %s%n", payment.paymentMethod(), payment.paymentDate()); } // Process shipping if applicable if (order.isShippable() && shipping != null) { System.out.printf(" Shipping to %s via %s%n", shipping.shippingAddress().city(), shipping.carrier()); } // Process items for (OrderItem item : items) { processOrderItem(item); } } private static void processOrderItem(OrderItem item) { String productName = item.productName(); int quantity = item.quantity(); double price = item.price(); double subtotal = item.subtotal(); System.out.printf(" %d x %s @ $%.2f = $%.2f%n", quantity, productName, price, subtotal); } // Complex analysis with multiple levels of nesting public static CustomerReport generateCustomerReport(Customer customer) { String customerId = customer.id(); String customerName = customer.name(); Address address = customer.address(); List<Order> orders = customer.orders(); // Calculate statistics long totalOrders = orders.size(); double totalSpent = orders.stream() .mapToDouble(Order::totalAmount) .sum(); double averageOrderValue = totalOrders > 0 ? totalSpent / totalOrders : 0; // Analyze order status distribution Map<OrderStatus, Long> statusCount = orders.stream() .collect(Collectors.groupingBy(Order::status, Collectors.counting())); // Find most expensive order Optional<Order> mostExpensiveOrder = orders.stream() .max(Comparator.comparing(Order::totalAmount)); return new CustomerReport( customerId, customerName, address.city(), address.country(), totalOrders, totalSpent, averageOrderValue, statusCount, mostExpensiveOrder.map(Order::totalAmount).orElse(0.0) ); } public record CustomerReport( String customerId, String customerName, String city, String country, long totalOrders, double totalSpent, double averageOrderValue, Map<OrderStatus, Long> orderStatusDistribution, double mostExpensiveOrder ) { public void print() { System.out.printf("Customer Report: %s (%s)%n", customerName, customerId); System.out.printf("Location: %s, %s%n", city, country); System.out.printf("Orders: %d, Total Spent: $%.2f, Avg Order: $%.2f%n", totalOrders, totalSpent, averageOrderValue); System.out.println("Order Status Distribution:"); orderStatusDistribution.forEach((status, count) -> System.out.printf(" %s: %d%n", status, count)); System.out.printf("Most Expensive Order: $%.2f%n", mostExpensiveOrder); } } // Pattern matching with collections public static void processCustomerOrders(List<Customer> customers) { for (Customer customer : customers) { // Extract customer data String customerName = customer.name(); List<Order> orders = customer.orders(); // Filter and process orders List<Order> recentOrders = orders.stream() .filter(order -> order.orderDate().isAfter(Instant.now().minusSeconds(30 * 24 * 60 * 60))) .collect(Collectors.toList()); List<Order> highValueOrders = recentOrders.stream() .filter(order -> order.totalAmount() > 1000) .collect(Collectors.toList()); // Process high-value orders for (Order order : highValueOrders) { processHighValueOrder(customerName, order); } } } private static void processHighValueOrder(String customerName, Order order) { System.out.printf("High value order from %s: %s - $%.2f%n", customerName, order.orderId(), order.totalAmount()); // Check if order needs special shipping if (order.totalAmount() > 5000) { System.out.println(" -> Requires premium shipping"); } } }

Real-World Use Cases

7. Practical Application Examples

// API Response processing with pattern matching public class ApiResponseProcessor { public sealed interface ApiResponse<T> permits Success, Error, Loading, Empty { boolean isSuccess(); default boolean isError() { return !isSuccess(); } } public record Success<T>(T data, String message, int statusCode) implements ApiResponse<T> { @Override public boolean isSuccess() { return true; } } public record Error<T>(String errorCode, String message, Throwable cause) implements ApiResponse<T> { @Override public boolean isSuccess() { return false; } } public record Loading<T>(String progressMessage) implements ApiResponse<T> { @Override public boolean isSuccess() { return false; } } public record Empty<T>() implements ApiResponse<T> { @Override public boolean isSuccess() { return false; } } // Process API responses with pattern matching public static <T> void handleApiResponse(ApiResponse<T> response) { switch (response) { case Success<T> success -> { T data = success.data(); String message = success.message(); int statusCode = success.statusCode(); System.out.printf("Success (%d): %s%n", statusCode, message); processSuccessData(data); } case Error<T> error -> { String errorCode = error.errorCode(); String errorMessage = error.message(); Throwable cause = error.cause(); System.err.printf("Error %s: %s%n", errorCode, errorMessage); if (cause != null) { cause.printStackTrace(); } } case Loading<T> loading -> { String progress = loading.progressMessage(); System.out.println("Loading: " + progress); } case Empty<T> empty -> { System.out.println("No data available"); } } } private static <T> void processSuccessData(T data) { // Type-specific processing based on data type if (data instanceof List<?> list) { System.out.println("Received list with " + list.size() + " items"); } else if (data instanceof Map<?, ?> map) { System.out.println("Received map with " + map.size() + " entries"); } else if (data instanceof String str) { System.out.println("Received string: " + str); } else { System.out.println("Received data: " + data); } } // Process multiple API responses public static void processMultipleResponses(List<ApiResponse<?>> responses) { for (ApiResponse<?> response : responses) { if (response instanceof Success<?> success) { Object data = success.data(); System.out.println("Processing successful response with data: " + data); } else if (response instanceof Error<?> error) { System.err.println("Error encountered: " + error.message()); } } } } // Configuration processing with deconstruction public class ConfigurationProcessor { public record DatabaseConfig( String url, String username, String password, int poolSize, Map<String, String> properties ) { public DatabaseConfig { if (poolSize <= 0) { throw new IllegalArgumentException("Pool size must be positive"); } if (properties == null) { properties = new HashMap<>(); } } } public record ServerConfig( String host, int port, boolean sslEnabled, int maxConnections, List<String> allowedOrigins ) { public ServerConfig { if (port < 1 || port > 65535) { throw new IllegalArgumentException("Invalid port number"); } if (allowedOrigins == null) { allowedOrigins = new ArrayList<>(); } } } public record AppConfig( String name, String version, DatabaseConfig database, ServerConfig server, Map<String, Object> features ) { public AppConfig { if (features == null) { features = new HashMap<>(); } } } public static void validateAndProcessConfig(AppConfig config) { // Deconstruct configuration String appName = config.name(); String version = config.version(); DatabaseConfig dbConfig = config.database(); ServerConfig serverConfig = config.server(); Map<String, Object> features = config.features(); // Validate database configuration validateDatabaseConfig(dbConfig); // Validate server configuration validateServerConfig(serverConfig); // Process features processFeatures(features); System.out.printf("Configuration validated for %s v%s%n", appName, version); } private static void validateDatabaseConfig(DatabaseConfig dbConfig) { String url = dbConfig.url(); String username = dbConfig.username(); int poolSize = dbConfig.poolSize(); if (url == null || url.isBlank()) { throw new IllegalArgumentException("Database URL is required"); } if (username == null || username.isBlank()) { throw new IllegalArgumentException("Database username is required"); } if (poolSize > 100) { System.out.println("Warning: Large connection pool size: " + poolSize); } } private static void validateServerConfig(ServerConfig serverConfig) { String host = serverConfig.host(); int port = serverConfig.port(); boolean sslEnabled = serverConfig.sslEnabled(); if (host == null || host.isBlank()) { throw new IllegalArgumentException("Server host is required"); } if (sslEnabled && port == 80) { System.out.println("Warning: SSL enabled but using HTTP port 80"); } } private static void processFeatures(Map<String, Object> features) { for (Map.Entry<String, Object> entry : features.entrySet()) { String featureName = entry.getKey(); Object featureConfig = entry.getValue(); // Pattern matching on feature configuration type if (featureConfig instanceof Boolean enabled) { System.out.printf("Feature %s: %s%n", featureName, enabled ? "ENABLED" : "DISABLED"); } else if (featureConfig instanceof Map<?, ?> nestedConfig) { System.out.printf("Feature %s has nested configuration with %d settings%n", featureName, nestedConfig.size()); } else if (featureConfig instanceof List<?> list) { System.out.printf("Feature %s has list configuration with %d items%n", featureName, list.size()); } } } }

This comprehensive guide covers Java's deconstruction patterns from basic record usage to advanced nested pattern matching, providing practical examples and real-world use cases for modern Java development.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper