// 사용 전
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Article)) return false;
				Article article = (Article) o
        return id.equals(article.id);
    }

		// 사용 후
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Article article)) return false;
        return id.equals(article.id);
    }

예제) 모양별 둘레 계산 하는 코드

public interface Shape { }

final class Rectangle implements Shape {
    final double length;
    final double width;
    
    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }
    
    double length() { return length; }
    double width() { return width; }
}

public class Circle implements Shape {
    final double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    double radius() { return radius; }
}

    public static double getPerimeter(Shape shape) throws IllegalArgumentException {
        if (shape instanceof Rectangle) {
            Rectangle s = (Rectangle) shape;
            return 2 * s.length() + 2 * s.width();
        } else if (shape instanceof Circle) {
            Circle s = (Circle) shape;
            return 2 * s.radius() * Math.PI;
        } else {
            throw new IllegalArgumentException("Unrecognized shape");
        }
    }

getPerimeter 는 다음과 같다.

  1. Shape 객체의 유형을 확인.
  2. 유형에 따른 Shape 으로 캐스팅 해줌.
  3. Shape 객체에서 길이와 너비 또는 반지름을 추출.

instanceof 패턴 일치를 사용하면 형식 테스트 패턴으로 코드를 더 짧고 읽기 쉽게 만들 수 있음.

캐스팅 단계를 제거하면 코드가 더 안전해짐.