맞는데 왜 틀릴까..?

Java/Effective Java 77

[Effective Java] Item 12. toString을 항상 재정의하라

Object의 기본 toString 메서드가 우리가 작성한 클래스에 적합한 문자열을 반환하는 경우는 거의 없다. PhoneNumber@adbbd 처럼 단순히 클래스_이름@16진수로_표시한_해시코드를 반환할 뿐이다. toString의 규약은 모든 하위 클래스에서 이 메서드를 재정의 하라고 한다. toString은 프로그래머가 직접 호출하지 않더라도 println. printf, 문자열 연결 연산자(+), assert 구문에 넘길 때, 혹은 디버거가 객체를 출력할 때 등등 자동으로 불린다. 따라서 toString을 항상 재정의 해주자. toString은 그 객체가 가진 주요 정보 모두를 반환하는게 좋다. 만약 객체가 거대하거나 문자열로 표현하기 적합하지 않다면 요약 정보를 담자. toString을 구현할 때..

Java/Effective Java 2023.03.09

[Effective Java] Item 11. equals를 재정의 하려거든 hashCode도 재정의 하라

자바에서 hashCode()는 객체의 해시 코드를 반환하는 메서드다. 해시 코드란 객체를 구분하기 위해 생성된 고유한 정수값으로, 자바의 HashMap, HashSet 등과 같은 자료구조에서 객체를 식별하는 데 사용된다. hashCode() 메서드는 Object 클래스에서 정의되어 있으며, 모든 자바 객체가 이를 상속하는데 Object 클래스에서 구현된 기본 hashCode()는 객체의 메모리 주소에 기반하여 해시 코드를 생성한다. Object 클래스에 정의된 hashCode의 규약을 살펴보자. 1. equals 비교에 사용되는 정보가 변경되지 않았다면, 애플리케이션이 실행되는 동안 그 객체의 hashCode 메서드는 몇 번을 호출해도 항상 같은 값을 반환해야 한다. 2. equals(Object)가 두..

Java/Effective Java 2023.03.08

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

꼭 필요한 경우가 아니면 equals를 재정의 하지 말자. 많은 경우에 Object의 equals가 프로그래머가 원하는 비교를 정확히 수행해 준다. 재정의 해야 할 때는 그 클래스의 핵심 필드 모두를 빠짐없이, 다섯 가지 규약을 확실히 지켜가며 비교해야 한다. 다음과 같은 경우에는 equals를 재정의 하지 말자 1. 각 인스턴스가 본질적으로 고유할 때 (ex 객체가 파일일 때 파일의 경로나 이름 등은 다른 객체와 같지 않고 고유하기 때문이 equals를 재정의 할 필요가 없다.) 2. 인스턴스의 논리적 동치성을 검사할 일이 없을 때 3. 상위 클래스에서 재정의한 equals가 하위 클래스에도 들어맞을 때 4. 클래스가 private이거나 package-private이고 equals 메서드를 호출할 일이..

Java/Effective Java 2023.03.07

[Effective Java] Item 9. try-finally 보다는 try-with-resources 를 사용하라

전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰였지만 몇 개의 단점이 있다. 단점 1. try와 finally 블록 모두에서 예외가 발생했을 때 예외는 try 블록과 finally 블록 모두에서 발생할 수 있다. 만약 기기에 물리적 문제가 생겨 firstLineOfFile 메서드 try 블록의 readLine 메서드와 finally 블록의 close 메서드가 실패했다면 두 번째 예외가 첫 번째 예외를 집어삼켜버린다. 그렇다면 첫 번째 예외에 관한 정보는 남지 않게 되어 디버깅이 상당히 어려워진다. 단점 2. 자원이 여러 개일 때 만약 자원이 하나가 아니라 자원이 둘 이상이라면 try-finally 방식의 코드는 매우 지저분해진다. 이러한 단점 때문에 우리는 try-with-r..

Java/Effective Java 2023.03.07

[Effective Java] Item 8. finalizer 와 cleaner 사용을 피하라

finalizer와 cleaner는 C++의 파괴자와는 다른 개념이다. C++에서의 파괴자는 생성자의 꼭 필요한 대척점으로 특정 객체와 관련된 자원을 회수하는 보편적인 방법이다. 하지만 자바에서는 접근할 수 없게 된 객체를 회수하는 역할을 가비지 컬렉터가 담당하고, 프로그래머에게는 아무런 작업도 요구하지 않는다. C++의 파괴자는 비메모리 자원을 회수하는 용도로 쓰인다. 하지만 자바에서는 try-with-resources와 try-finally를 사용해 해결한다. 자바 9 이전에는 finalizer를, 이후에는 그 대안으로 cleaner를 제공하지만 둘 다 위험하고, 예측할 수 없으며 느리고 일반적으로 불필요하다. 단점을 살펴보자. 1. finalizer와 cleaner는 즉시 수행된다는 보장이 없다. ..

Java/Effective Java 2023.03.05

[Effective Java] Item 7. 다 쓴 객체 참조를 해제하라

자바 전공 수업에서 교수님이 자바의 특징 중에서 강조하신 것이 가비지 컬렉터를 가진 언어라는 것이었다. C나 C++ 처럼 일일이 메모리를 해제해주지 않아도 되어서 매우 편했지만 이렇게 맘 편히 메모리 관리에 신경 쓰지 않아도 되는 것이 아니었다! 자바에서는 메모리 관련해서 숨겨져 있는 문제가 있는데 바로 '메모리 누수'이다. 메모리 누수가 일어나는 3가지 경우를 살펴보자. 1. 자기 메모리를 직접 관리하는 클래스 대표적인 예를 살펴보자. public class Stack { private Object[] elements; private int top = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements ..

Java/Effective Java 2023.03.04

[Effective Java] Item 1~6. 객체 생성과 파괴

객체를 만들어야 할 때와 만들지 말아야 할 때를 구분하고, 올바른 객체 생성 방법과 불필요한 생성을 피하는 방법, 제때 파괴됨을 보장하고 파괴 전에 수행해야 할 정리 작업을 관리하는 요령을 알아보자. - Effective Java p7 정적 팩토리 메서드 생성자 호출 방식(new)이 아닌, 메서드 호출 방식으로 객체를 생성하는 것. 1. 생성자 대신 정적 팩터리 메서드를 고려하라 1-1 이름을 가질 수 있다. 생성자로 호출 하는 방식은 해당 클래스의 생성자가 여러 가지일 경우에 어떤 객체가 반환되는지 쉽게 알 수 없다. 예를 들어보자 유저 클래스 public class User { private String id; private String password; } public class User { pri..

Java/Effective Java 2023.03.01