16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라 클래스 내부의 field에 접근하기 위해 이 필드를 public으로 열어 직접 접근하게 하는것이 아닌 private으로 선언하고 이에 접근하는 메소드를 제공해야한다. // 코드 16-2 접근자와 변경자(mutator) 메서드를 활용해 데이터를 캡슐화한다. (102쪽) class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } public void setX(doub..
13. clone 재정의는 주의해서 진행하라 Object는 protected 메소드인 clone을 가지고 있다. 이 메소드를 재정의 하기 위해서는 Cloneable interface를 구현해야한다. Cloneable interface에는 어떠한 메소드도 정의 되어 있지 않지만, 이를 구현한 클래스에서 clone을 호출하면 해당 클래스의 필드들을 하나하나 복사한 인스턴스를 새로 반환해 준다. 필드들이 primitive 타입만 존재한다면 Cloneable이 만들어 준 clone을 그대로 사용해도 되지만 reference 타입의 필드가 존재하면 deep copy가 이루어지지 않아 clone을 재정의 해주어야한다. public final class PhoneNumber implements Cloneable { ..
work bench 상에서 json 파일을 import 하는 것은 wizard를 사용해서 손쉽게 할 수 있습니다. 그러나 docker container 위에 띄워진 mysql에 이를 import 하기 위해서는 shell script로 밖에 할 수 없습니다. chatGPT의 도움을 빌어 json 파일을 import 해보려 했으나 json 파일과 table column의 순서가 달라 import가 되지 않았습니다. (wizard가 이런걸 자동으로 바꿔주는 듯하다.) 그래서 택한 방법 wizard로 import 된 data를 sql 구문으로 Export 하여 해당 sql문을 shell script로 실행합니다. 우선 sql dump를 실행하기 위해서 docker container안의 directory에 sql..
eqauls를 재정의한 클래스는 hashCode 또한 재정의 해야 한다. 이는 HashMap이나 HashSet과 같은 컬렉션의 원소 비교방법 때문이다. public final class PhoneNumber { private final short areaCode, prefix, lineNum; public PhoneNumber(int areaCode, int prefix, int lineNum) { this.areaCode = rangeCheck(areaCode, 999, "area code"); this.prefix = rangeCheck(prefix, 999, "prefix"); this.lineNum = rangeCheck(lineNum, 9999, "line num"); } private stat..
Java로 알고리즘 풀 때 Overriding 해 본 equals이다. equals를 재정의 하면 안되는 조건에 대해 소개해준다. 각 인스턴스가 본질적으로 고유하다. Object는 기본적으로 equals 메소드의 비교를 레퍼런스가 같은지를 확인한다. Thread와 같이 값을 표현하는 것이 아닌 동작하는 개체를 표현하는 클래스는 재정의 하지 않는 것이 좋다. 인스턴스의 논리적 동치성(logical equality)을 검사할 일이 없다. 두 인스턴스가 물리적으로 같은지가 아닌 논리적으로 같은지를 확인해야 할 때 재정의가 필요하다. 클라이언트 코드에서 이를 호출할 일도 없고 필요도 없다면 굳이 재정의할 필요가 없다. 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다. 설계를 완벽하게 해서 ..
자바 라이브러리에는 InputStream, OutputStream, java.sql.Connection과 같이 자원을 할당받고 회수해야 하는 친구들이 많다. I/O 작업과 관련 된 녀석들이 그런 것 같다. 클래스 내부로직에서 Exception이 발생해 close 메소드를 호출하지 못할 수 있다. 따라서 전통적으로 try-finally 블록을 통해 모든 로직의 끝에는 항상 close를 호출하게 구현을 했었다. static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br..
난생처음 보는 메소드들이다. 현재 finalizer는 Java 9 버전 이상에서 deprecated 됐다. 어차피 쓰지도 않을 녀석들이니 어떠한 사유로 deprecated 됐는지 이유를 가볍게 알아보고 넘어가면 좋을 것 같다. finalizer는 gc가 발생하기 이전 실행 돼야 할 전처리를 담당하는 메소드이다. 이는 C++의 소멸자(destructor)와 다르다. C++은 클래스 내부에서 heap 영역에 메모리를 동적 할당하고 할당된 메모리 해제와 관련한 로직을 직접 작성해야 한다. #include using namespace std; class testClass { public: testClass() { cout
Java에서는 C나 C++에서 처럼 메모리 관리에 대한 고민을 할 필요가 없다. 가비지 콜렉터가 판단해 사용되지 않는 메모리를 해제해 주기 때문이다. 오호 이제 메모리 관리는 신경을 쓰지 않아도 되겠군!이라고 생각했다면 만만의 콩떡이다. package effectivejava.chapter2.item7; import java.util.*; // 코드 7-1 메모리 누수가 일어나는 위치는 어디인가? (36쪽) public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEF..