// Old way (before pattern matching)
Object obj = "Hello";
if (obj instanceof String) {
    String str = (String) obj; // Explicit cast
    System.out.println(str.length());
}

// New way with pattern matching (Java 16+)
Object obj2 = "Hello";
if (obj2 instanceof String str) {
    // str is automatically cast and available
    System.out.println(str.length());
}

// Pattern matching with conditions
Object obj3 = "Hello World";
if (obj3 instanceof String s && s.length() > 5) {
    System.out.println("Long string: " + s);
}

// Pattern matching in switch (Java 17+)
Object value = 42;
String result = switch (value) {
    case String s -> "String: " + s;
    case Integer i -> "Integer: " + i;
    case Double d -> "Double: " + d;
    case null -> "Null";
    default -> "Unknown";
};

// Pattern matching with sealed classes
Shape shape = new Circle(5.0);
double area = switch (shape) {
    case Circle c -> Math.PI * c.radius() * c.radius();
    case Rectangle r -> r.width() * r.height();
    case Triangle t -> 0.5 * t.base() * t.height();
};

// Pattern matching with records
record Person(String name, int age) {}

Person person = new Person("Alice", 25);
String description = switch (person) {
    case Person(String name, int age) when age < 18 -> name + " is a minor";
    case Person(String name, int age) -> name + " is " + age + " years old";
};

// Nested pattern matching
record Point(int x, int y) {}
record Line(Point start, Point end) {}

Line line = new Line(new Point(0, 0), new Point(10, 10));
String lineInfo = switch (line) {
    case Line(Point(int x1, int y1), Point(int x2, int y2)) ->
        "Line from (" + x1 + "," + y1 + ") to (" + x2 + "," + y2 + ")";
};