본문 바로가기

Programming128

[Effective Java] 제네릭(Generic) 활용하기 (1) 오늘은 제네릭에 대해 정리해두려 한다. 제네릭 용어 정리 한글 용어 영문 용어 예 매개변수화 타입 parameterized type List 실제 타입 매개변수 actual type parameter String 제네릭 타입 generic type List 정규 타입 매개변수 formal type parameter E 비한정적 와일드카드 타입 unbounded wildcard type List 로 타입 raw type List 한정적 타입 매개변수 bounded type parameter 재귀적 타입 한정 recursive type bound 한정적 와일드카드 타입 bounded wildcard type List s2 = (Set) s1; for(Object o : s2) { if(o instancof .. 2023. 2. 10.
[Effective Java] 인터페이스 활용하기 자바를 처음 접한 사람이라면 누구나 인터페이스를 왜 쓰는지에 대한 의문을 가진적이 있을 것이다. 추상클래스만으로도 충분히 사용이 가능할 것 같고, 오히려 인터페이스를 쓰면 프로그램의 복잡도만 올라갈 것 같은데라는 생각을 아마도 하지 않았을까 생각한다. 허나 인터페이스는 객체지향의 세계를 구현하기 위한 가장 중요한 요소중 하나이다. 오늘은 이 인터페이스에 대해 정리를 좀 해두겠다. 먼저 확장과 구현에 대한 개념을 정리해두자. 클래스의 확장과 인터페이스의 구현의 가장 큰 차이는 클래스의 확장은 하나만 가능한 반면 인터페이스의 구현은 여러개가 가능하다. public class Sub extends Super implements Serializable, Cloneable { ... } 그리고 인터페이스는 여러개.. 2023. 2. 9.
[Effective Java] 상속 금지시키기 앞선 글에서 상속대신 컴포지션을 이용하라는 글을 작성했었다. https://devkingdom.tistory.com/371 [Effective Java] 상속 대신 컴포지션 이용하기 Effective Java에 따르면 상속 대신 컴포지션을 이용하라는 말이 있다. 이는 상속을 사용하게 되는 경우 상위클래스가 하위클래스에 영향을 끼쳐 대응할 수 없는 오류를 야기할 수 도 있고, 추후에 devkingdom.tistory.com 이는 다르게 말하면 상속은 완벽한 설계가 되어있는 상황이 아니라면 쓰지말라는 이야기가 될 수 있다. 하지만 내가 안쓴다고 다른 개발자들도 과연 안쓸까? 쓰지말라고 문서화를 열심히 해둬도 시간이 지나면 누군가는 잘못된 상속을 사용하고 있는 것을 볼 수가 있다. 진짜 상속을 사용해야겠다 싶.. 2023. 2. 8.
[Effective Java] 상속 대신 컴포지션 이용하기 Effective Java에 따르면 상속 대신 컴포지션을 이용하라는 말이 있다. 이는 상속을 사용하게 되는 경우 상위클래스가 하위클래스에 영향을 끼쳐 대응할 수 없는 오류를 야기할 수 도 있고, 추후에 수정이 일어날때 영향도가 높아 손봐야할 코드가 많아질 수 있다. (만약 상속을 정말 써야한다면 완벽에 가까운 설계를 하고 심사숙고하여 사용하길 바란다. 즉, 완벽한 is-a 관계가 유지될 때 상속을 사용하자) 이를 대응하기 위한 방법으로 우리는 컴포지션 패턴을 이용할 수 있다. 아래 예시를 보자 간단하게 여행사의 여행 정보를 예약하는 시스템을 만든다고 가정했다. (설명을 위한 예제이니 양해부탁드린다.) interface TravelInfo { void reserve(); } class Accommodati.. 2023. 2. 8.
[Effective Java] 불변 클래스 (Immutable class) 불변 클래스 (Immutable class) 는 말 그대로 인스턴스 내부의 값을 수정할 수 없는 클래스다. 클래스를 불변으로 만들면 가변 클래스보다 훨씬 설계하고 구현하고 사용하기 쉽고, 오류없이 안전하게 사용이 가능하다. 불변 클래스 (Immutable class) 는 Thread safe 해야하고, 예외가 발생해도 유효한 상태를 유지해야하며, 값이 다르다면 무조건 독립적인 객체로 생성되어야한다. 불변 클래스 (Immutable class) 를 만들기 위해서는 아래 다섯가지 특징을 따라야 한다. 1. 상태를 변경하는 메서드 (setter 메서드 등) 을 제공하지 않는다. 2. Class 가 확장하지 않도록 한다 (final class) 3. 모든 필드에 final으로 선언한다. 4. 모든 필드를 pri.. 2023. 2. 7.
[Effective Java] public static final 만약 클래스의 특정 필드를 public으로 열어두면 어떤일이 발생할까? public 으로 공개된 필드는 Thread Safe 하지 못하다. 즉 Lock 관련 작업(synchronized 로 처리한다거나 @Transactional 어노테이션으로 순서를 보장한다던가 하는 작업...)을 걸 수가 없다는 뜻이다. 이는 프로그램에 심각한 문제를 일으킬 수 있는 요소가 된다. 예를 들어 은행 계좌 클래스가 있거 금액을 의미하는 필드가 있을때 이 필드가 public으로 제공이 되는 경우에는 동시 다발적으로 금액 필드에 접근하여 심각한 문제를 야기할 수 있다는 말이다. 만약에 정말 필요한 상수로 사용할 생각이라면 필드를 public static final 을 통해서 공개가 가능하다. private class Item .. 2023. 2. 7.
[Effective java] 객체 순서 비교하기 - compareTo 오늘은 굉장히 많이 쓰이는 compareTo에 대해 정리해두려 한다. compareTo는 객체간의 순서를 비교하기 위해 사용된다. 기본적인 동작 방식은 compareTo 는 비교하고자하는 객체보다 작으면 -1을 , 같으면 0을, 크면 1을 반환한다. 만약 비교할 수 없을 경우에는 ClassCastException을 반환하는 것 까지 알아 두자. comareTo 메서드 역시 여느 메서드와 마찬가지로 오버라이딩해서 사용이 가능하다. 하지만 역시나 특정한 조건을 만족해야 된다. 이전에 equals 메서드를 정리한 것처럼 , compareTo는 equals와 조건이 비슷하다. 아래 sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) x.compareTo(y) > 0 && y.compa.. 2023. 2. 4.
[Effective java] 공통 메서드 정리 - clone 자바에서 제공하는 copy에는 두가지 종류가 있다. shallow copy 와 deep copy가 있다. 아래 예제를 보자. int[] a = {10, 20, 30, 40}; int[] b = a; //shallow copy b = a.clone(); //deep copy shallow copy를 하게 되면 객체의 주소값이 다른 객체에 할당이 될뿐 내부의 값자체가 카피되진 않는다. 내부의 값도 복사하기 위해선 deep copy를 해야하는데 자바에서는 clone이라는 메서드를 제공한다. 하지만 기본형 타입의 배열이 아닌 객체의 배열을 copy할때에는 큰 문제가 생길수 있다. 아래코드를 보자. Member[] m1 = {new Member("홍길동","abcd@gmail.com")}; Member[] m2 .. 2023. 2. 2.
[Effective Java] 공통 메서드 정리 - toString 오늘은 toString 메서드에 대해 정리하고자한다. 보통 객체의 toString 메서드를 호출하면 default 값으로 아래와 같은 형태로 값이 리턴된다. className@16진수hashcode값 허나 많은 회사에서 toString 메서드를 오버라이딩하는 경우가 많은데, toString을 오버라이딩 하면 굉장히 많은 이점을 얻을 수 있다. 예를 들어 정말 필요한 정보를 보기 쉽게 제공하게 만들어줘서 다양한 상황에서 오류트래킹이나 디버깅이 쉽게 되도록 도와줄 수가 있다. 또한 로깅이 필요할 때는 toString을 오버라이딩하면 최적화된 로그를 남길수가 있다. Effective Java의 책에 나온 것처럼 직접 toString 메서드를 재정의 해줄 수도 있지만, Lombok을 이용한다면 아주 최적화된 t.. 2023. 2. 2.