책/Effective Java

    @Override 어노테이션 사용법

    @Override - 메서드 선언에만 달 수 있으며, 이 어노테이션의 의미는 상위 타입(부모 타입)의 메서드를 재정의했음을 의미한다. @Override 어노테이션을 일관되게 사용한다면 여러 악명 높은 버그들을 예방할 수 있는 아주 좋은 습관이라고 말할 수 있다. Ex) 영어 알파벳 2개로 구성된 문자열을 표현하는 클래스 //버그를 찾아보자 public class Bigram { private final char first; private final char second; public Bigram(char first, char second) { this.first = first; this.second = second; } public boolean equals(Bigram bigram) { return b..

    클래스 계층 구조를 활용하기

    # 태그 달린 클래스 두 가지 이상의 의미를 표현할 수 있고, 그 중 현재 표현하는 의미를 태그 값으로 알려주는 클래스 class Figure { enum Shape { RECTANGLE, CIRCLE }; // 태그 필드 - 현재 모양을 나타낸다. final Shape shape; // 다음 필드들은 모양이 사각형(RECTANGLE)일 때만 쓰인다. double length; double width; // 다음 필드는 모양이 원(CIRCLE)일 때만 쓰인다. double radius; // 원용 생성자 Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } // 사각형용 생성자 Figure(double length, double wi..

    인터페이스 - 타입을 정의하는 용도로만 사용하기

    인터페이스의 역할 인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할을 한다. → 클래스가 인터페이스를 구현한다는 것 : 자신의 인스턴스로 무엇을 할 수 있는 지 의미를 전달 인터페이스는 위에서 언급한 용도로만 사용되어야 한다. 잘못된 인터페이스의 용도 상수 인터페이스 상수 인터페이스 : 메서드 없이, 상수를 뜻하는 static final 필드로 구성된 인터페이스 public interface PhysicalConstants { // 아보가드로 수 (1/몰) static final double AVOGADROS_NUMBER = 6.022_140_857e23; // 볼츠만 상수 (J/K) static final double BOLTZMANN_CONSTANT = 1.380_648_52e..

    인터페이스 설계 - 구현하는 개발자를 생각하자

    # default Method 자바 8 이전 기존 구현체를 깨뜨리지 않고, 인터페이스에 메서드 추가 방법 전무후무 - 인터페이스에 메서드 추가하면 대부분 컴파일 오류 발생 - 추가된 메서드가 기존 구현체에 존재할 가능성 희박 자바 8 이후 기존 인터페이스에 메서드를 추가할 수 있도록 디폴트 메서드 추가 핵심 컬렉션 인터페이스들에 많은 디폴트 메서드 추가 for lambda 활용 디폴트 메서드 선언시, 그 인터페이스를 구현한 후에 디폴트 메서드를 재정의하지 않은 모든 클래스에서는 디폴트 구현이 사용 단, 디폴트 메서드는 구현 클래스에 대한 정보 없이 무작정 삽입(추가) 된 것이므로 주의해야 한다. 자바 라이브러리의 디폴트 매서드는 코드 품질이 높고 범용적이므로 대부분의 상황에서 잘 작동 하지만, 생각할 수..

    인터페이스가 추상 클래스보다 우선인 이유

    자바가 제공하는 다중 구현 메커니즘 - Interface (자바 8부터 default 메서드 제공) - Abstract Class 인터페이스와 추상 클래스 공통점 선언 내용은 존재, 하지만 구현 내용은 없음(추상 메서드를 가진다) 인스턴스 생성이 불가하다. 각각의 목적 인터페이스 Has - A 관계 : 함수의 껍데기만 존재하여 구현을 강제화 함 이를 통해 구현 객체가 같은 동작을 하도록 보장 다중 상속 - 여러개의 인터페이스를 구현이 가능하다. 인스턴스 필드를 가질 수 없고, public이 아닌 정적 멤버도 가질 수 없다(자바 9 부터 private static 메서드 구현 가능) 추상 클래스 IS - A 관계 : 추상 클래스를 상속하여 해당 클래스의 기능을 이용하고 또는 기능을 추가한다. 다중 상속 -..

    equals 재정의

    일단, 결론부터 얘기하자면 Object Class를 믿고, equals 꼭 필요한 것이 아니면 재정의하지 말자 그래도 반드시 재정의를 해야할 때가 있을 수 있으니 고려하고 준수해야할 사항들을 살펴보도록 하자. # 재정의하지 않는 것이 좋은지 다시 확인 재정의하지 않는 것이 최선인 상황들이 존재한다. 각 인스턴스가 본질적으로 고유할 때 ex) 동작하는 개체를 표현하는 클래스 - Thread 인스턴스의 논리적 동치성(logical equality)을 검사할 일이 없을 때 상위 클래스에서 재정의한 equals가 하위클래스에서도 적절하게 동작할 때 Constructor Set / List / Map 은 모두 AbstractSet / AbstractList / AbstractMap 으로부터 상속받아서 그대로 사용..

    다 쓴 객체 참조 해제하기

    자바에서는 가비지 컬렉터(GC)가 사용하지 않는 객체들에 대해서 메모리를 알아서 관리해준다. 먼저 가비지 컬렉션에 대해 간단하게만 짚고 넘어가보자 # GC (Garbage Collection) 힙 영역 내의 참조되지 않는 객체가 아닌 Reachability 라는 개념을 통해 도달되지 않는 객체를 메모리에서 해제하여 메모리 관리를 해준다. 가비지 컬렉션의 동작 방식 Heap 에서의 Young 영역과 Old영역은 서로 다른 메모리 구조기 때문에, 세부적으로는 가비지 컬렉터가 다르게 동작하지만, 기본적으로 가비지 컬렉션은 2가지의 공통된 단계를 거친다. Stop The World 가비지 컬렉션을 실행하기 위해 JVM이 실행중인 GC를 진행하는 쓰레드를 제외한 모든 쓰레드의 작업을 중단하여 애플리케이션의 실행이..

    불필요한 객체 생성 피하는 방법

    static boolean isRomanNumeral(String s) { return s.matches(" ... "); } # 정적 팩토리 메서드 방법 똑같은 기능을 제공하는 객체를 반복적으로 생성하는 것보다 객체 하나를 재사용하는 것이 더 효율적 /* 실행될 때마다 new 를 통해 새로운 인스턴스 생성 - 쓸데없는 String 인스턴스가 계속해서 생성된다. */ String s = new String("Xonmin"); /* 하나의 String 인스턴스 생성 JVM 안에서 이와 똑같은 문자열 리터럴을 사용하는 모든 코드는 같은 객체를 재사용하게 된다. */ String s = "Xonmin"; 생성자 대신 정적 팩토리 메서드를 통해 불변 클래스에서 불필요한 객체 생성 회피 가변 객체라고 해도 사용 ..