이펙티브자바

    [Effective Java] Comparable을 구현할지 고려하라

    Comparable을 구현할지 고려하라 Comparable을 구현한다는 것은 그 클래스의 인스턴스들에 자연적인 순서를 부여하는 것이다. 알파벳, 숫자, 연대 같이 순서가 명확한 값 클래스를 작성할 때는 Comparable인터페이스를 구현하는 것이 좋다. Comparable 규약 BigDecimal n1 = BigDecimal.valueOf(12312312); BigDecimal n2 = BigDecimal.valueOf(22212322); BigDecimal n3 = BigDecimal.valueOf(12312312); BigDecimal n4 = BigDecimal.valueOf(22212322); // 1. 반사성 n1.compareTo(n1) => true // 2. 대칭성 n1.compareTo(..

    [Effective Java] toString을 재정의하라

    toString을 항상 재정의하라 Object의 기본 toString 메서드가 우리가 작성할 클래스에 적합한 문자열을 반환하는 경우는 없다. toString의 일반 규약 간결하면서 사람이 읽기 쉬운 형태의 유익한 정보 모든 하위클래스에서 이 메서드를 재정의한다 toString의 구현 toString은 그 객체가 가진 주요 정보를 모두 반환하는 것이 좋다. 반환값의 포맷을 문서화할지 정해야 한다. => 값 클래스라면 문서화를 권장한다. => 의도를 명확하게 표현한다. toString이 반환한 값에 포함된 정보를 얻어올 수 있는 API를 제공하자. => e.g 만약에 지역 코드와 가입자 번호의 정보를 toString에서 반환하고 있는 클래스라면 지역 코드, 가입자 번호 접근자를 제공해야 한다. => why ..

    [Effective Java] equals를 재정의하려거든 hashcode도 재정의하라

    [Effective Java] equals를 재정의하려거든 hashcode도 재정의하라

    hashcode 규약 equals 비교에 사용되는 정보가 변경되지 않았다면 hashcode는 항상 같은 값을 리턴해야 한다. 두 객체에 대한 equals가 같다면, hashcode의 값도 같아야 한다. 두 객체의 equals가 다르더라도, 같은 hashcode값을 가질 수 있다. 더 좋은 성능을 위해 다른 값을 리턴하는 것이 더 좋기는 하다. 다음 예제를 통해 왜 hashcode를 같이 정의해야 하는지 이해해보자. phoneNumber에는 equlas규약에 맞춰 메소드가 잘 정의되어있다고 가정하자. public class HashMapTest { public static void main(String[] args) { Map map = new HashMap(); PhoneNumber number1 = n..

    [Effective Java] equals는 일반 규약을 지켜 재정의하라

    equals의 재정의가 필요 없는 경우 다음과 같은 상황에서는 equals 메서드의 재정의가 필요하지 않다. 각 인스턴스가 본질적으로 고유하다. => 값을 표현하는 것이 아니라 동작하는 개체를 표현하는 클래스가 해당된다. => Thread가 좋은 예로 Object의 equals는 이러한 클래스에 딱 맞게 구현되어 있다. 인스턴스의 논리적 동치성을 검사할 일이 없다. 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다. 클래스가 private이거나 package-private이고 equals 메서드를 호출할 일이 없다. 다음과 같이 equals가 실수로 호출되는 것을 막을 수 있다. @Override public boolean equals(Object o) { throw new Asser..

    [Effective Java] 인스턴스화를 막으려거든 private 생성자를 사용하라

    정적 메서드와 정적 필드만 담은 클래스를 만들 때가 있다. 이런 경우 정적 멤버만 담은 유틸리티 클래스는 인스턴스로 만들어 쓰려고 설계한 것이 아니다. 하지만 생성자를 명시하지 않으면 컴파일러가 자동으로 기본 생성자를 만들어준다. 이 때문에 때때로 공개된 API들에서도 의도치 않게 인스턴스화할 수 있게 된 클래스가 보이곤 한다. 추상 클래스(abstract)를 이용하면 인스턴스화를 막을 수 있을 것이라고 생각하지만, 하위 클래스를 만들면 하위 클래스의 생성자에서 상위 클래스의 생성자를 호출하기 때문에 인스턴스화를 완전히 막지는 못한다. 인스턴스화를 완전히 막는 방법은 private 생성자를 추가하는 것이다. 이 방법은 상속을 불가능하게 하는 효과도 있다. public class UtilityClass {..