불변클래스 불변 클래스 : 한 번 만들어지면(초기화가 끝나면) 인스턴스가 소멸될 때 까지 상태가 바뀌지 않는 것(해당 클래스가 가지고 있는 필드 값) 불변 클래스는 가변 클래스보다 설계하고 구현하고 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다. 불변 클래스를 만드는 다섯가지 규칙 객체의 상태를 변경하는 메서드를 제공하지 않는다. 클래스를 확장할 수 없도록 한다. 모든 필드를 final로 선언한다. 모든 필드를 private로 선언한다. 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 한다. 불변 클래스는 가변 클래스보다 설계하고 구현하고 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다. 멀티 스레드 환경에서 스레드 세이프. 값이 변하지 않으니 여러 스레드에서 사용할 때 캐시해서..
클라이언트 코드가 필드를 직접 사용하면 캡슐화의 장점을 제공하지 못한다. 필드를 변경하려면 API를 변경해야 한다. 필드에 접근할 때 부수 작업을 할 수 없다. package-private 클래스 또는 private 중첩 클래스라면 데이터 필드를 노출해도 문제가 없다. public 클래스의 경우 권장되는 코드 불변 필드를 노출한 public 클래스 public 클래스는 어느 곳에서나 가져다 쓰는 API용 객체이기 때문에 public 필드를 직접 접근해 값을 변경하게 만들어 놓으면 필드명을 수정해야 할 때 가져다 쓴 곳을 일일이 찾아가며 변경해야하며 외부 클래스 메서드에서 값이 변경되는 코드가 들어간다면 생각치 못한 곳에서 값이 변경될 수 있다. package-private 클래스라면 필드명이 변경된다고 ..
구현과 API를 분리하는 "정보 은닉"의 장점 시스템 개발 속도를 높인다. (여러 컴포넌트를 병렬로 개발할 수 있기 때문에) 시스템 관리 비용을 낮춘다. (컴포넌트를 더 빨리 파악할 수 있기 때문에) 성능 최적화 도움을 준다. (프로파일링을 통해 최적화할 컴포넌트를 찾고 다른 컴포넌트에 영향을 주지 않고 해당 컴포넌트만 개선할 수 있기 때문에) 소프트웨어 재사용성을 높인다. (독자적인 컴포넌트라면) 시스템 개발 난이도를 낮춘다. (전체를 만들기 전에 개별 컴포넌트를 검증할 수 있기 때문에) 클래스와 인터페이스의 접근 제한자 사용 원칙 모든 클래스와 멤버의 접근성을 가능한 한 좁혀야 한다. 톱레벨 클래스(inner class가 아닌 가장 밖에 있는 class)와 인터페이스에 package-private(d..
Comparable 인터페이스의 메서드인 compareTo는 단순 동치성 비교에 더해 순서까지 비교하는 메서드이다. 자바 플랫폼 라이브러리 모든 값 클래스와 열거타입은 Comparable을 구현했다. 알파벳, 숫자, 연대 같은 순서가 명확한 값 클래스를 작성한다면 반드시 Comparable 인터페이스를 구현해라 comparable, Comparator는 왜 사용 할까? primitive 타입은 부등호로 쉽게 값을 비교하지만 우리가 만든 클래스는 무엇을 기준으로 객체를 비교할지 알 수없기 때문에 사용자가 기준을 정해주지 않는 이상 어떤 객체가 더 높은 우선순위를 갖는지 판단할 수 없다. 이름을 비교할 때 성을 우선순위로 생각하고 같은 객체인지 이름 순으로 할 지 알 수없다. compareTo 메서드의 일반..
clone 메서드? Object의 clone 메서드는 자기 자신의 인스턴스를 복사하는 기능을 가지고 있다. 생성된 인스턴스의 참조값을 다시 대입하는게 아니라 같은 인스턴스를 다시 다른 메모리공간에 생성하여 복사된 인스턴스의 참조값을 준다. 인스턴스 자체는 별개의 인스턴스로 복사를 했지만 정작 인스턴스에서 쓰이는 값들이 Reference Type 이라면 이전 원본의 참조값을 가지고 있어서 복사된 인스턴스의 상태값을 바꾸면 원본 인스턴스의 상태값도 변경이 된다. 불변 객체일 경우 한번 세팅된 상태값이 변경되지 않으니 복사본이 같은 참조값을 가져도 무방하다. 사용하기 좀 까다로운 메서드인데 접근제어자가 protected여서 같은 패키지, 상속받은 클래스일 경우만 해당 메서드를 사용할 수 있다. Overridi..
toString 메서드는 객체 자체의 정보를 알려주는 역할을 하는 메서드로 최상위 클래스인 Object에 선언되어 있다. Object에 선언된 기능은 해당 객체의 클래스 이름과 16진수로 변환한 해시코드가 출력이 된다. 실제로 사용하기엔 그닥 유용한 정보라고 할 수 없다. 값을 가진 클래스에서는 별도의 toString을 Overriding 하여 자기가 가진 값이 리턴되도록 재정의 해줘야 사용하기 편하다. Object 클래스의 toString 메서드는 클래스_이름@16진수로_표시한_해시코드 를 반환한다. String에서 this를 반환하는데 어떻게 문자열 그대로 출력이 되는지 의문.. 본인의 객체가 리턴되는 거면 참조하고 있는 해시코드값이 나와야 하는게 아닐지 왜 이미 자기자신이 문자열인지 모르겠다. th..
hashCode? 객체 해시코드란 객체를 식별하는 정수값으로 Object 클래스의 hashCode메서드는 Heap 메모리 영역에 인스턴스들이 자리한 위치값을 리턴해주기 때문에 인스턴스마다 다른 위치 참조값을 가지고 있다. 만약 값을 표현하는 객체가 새롭게 인스턴스를 생성하여 비교했을 때 논리적으로 같은객체로 봐야한다면 equals 메서드를 재정의 하면서 hashCode 메서드도 재정의 해줘야 한다. 그렇지 않으면 hashCode 일반 규약을 어기게되어 HashMap이나 HashSet 같은 컬렉션의 원소로 사용할 때 객체를 비교한다면 우선 hashCode 메서드를 실행해서 값이 다르면 다른 객체로 판단하고 같으면 equals 메서드로 다시 비교한다. Hash 컬렉션들은 형태로 데이터를 저장하는데 hashC..
equals() ? equals 메서드는 두 객체를 비교하는 기능으로 Object 클래스의 메서드여서 어느 클래스를 만들던 쓸 수 있는 기능이지만 Object 클래스의 equals 메서드는 단순히 해당 객체 참조값이 같은지 비교하는 메서드 이기 때문에 좀 더 구체적인 비교를 원한다면 메서드 Overriding 하여 구현해야 한다. 하지만 곳곳에 함정이 도사리고 있어 잘못 Overriding 하게되면 프로그램이 이상하게 동작하거나 종료될 것이고, 원인이 되는 코드를 찾기도 굉장히 어렵다. Object 클래스의 equals는 비교 연산자인 == 와 같은 기능을 하는 메서드로 각 인스턴스가 본질적으로 고유한 객체를 나타내는 클래스라면 Object의 equals 메서드가 적절히 구현되어 있어 굳이 재정의 할 필..