본문 바로가기

JAVA/Effective Java

item 27) 비검사 경고를 제거하라 0. 제네릭의 장점 컴파일 시 강한 타입 체크를 할 수 있습니다. 자바 컴파일러 코드에서 잘못 사용된 타입 때문에 발생하는 문제점을 제거하기 위해 제네릭 코드에 대한 강한 타입 체크를 합니다. 실행 시 타입 에러가 나는 것보다는 컴파일 시에 미리 타입을 강하게 체크해서 에러를 사전에 방지하는 것이 좋습니다. 타입 변환을 제거합니다. 비제네릭 코드는 불필요한 타입 변환을 하기 때문에 프로그램 성능에 악영향을 미칩니다. 다음 아래 코드를 보면 List에 문자열 요소를 저장했지만, 요소를 찾아올 때는 반드시 String으로 타입 변환을 해야합니다. List list = new ArrayList(); list.add("hello"); String str = (String) list.get(0); //타입 변환 .. 더보기
item 24) 멤버 클래스는 되도록 static으로 만들라 1. 중첩 클래스(Nested Class) - 다른 클래스 안에 정의된 클래스 (자신을 감싼 바깥 클래스 에서만 사용되어야 하며, 그 외의 쓰임새가 잇다면 톱레벨 클래스로 따로 클래스 파일에 정의해야함 종류 정적 멤버 클래스 (비정적) 멤버 클래스 익명 클래스 지역 클래스 2. 각각의 특징 정적 멤버 클래스 vs 비정적 클래스 (클래스 앞에 static 키워드가 붙냐 안붙냐 차이) - 비정적 클래스는 바깥 클래스의 인스턴스와 암묵적으로 참조함(바깥 인스턴스의 메소드 및 참조 접근 가능) - 바깥 인스턴스와 독립적인 존재로 만들고 싶다면 반드시 정적 멤버 클래스로 선언해야함(비 정적 클래스는 참조를 지우더라도 바깥 클래스가 계속해서 참조하므로 가비지 컬렉션이 메모리를 수거하지 못함) - 비정적 멤버 클래.. 더보기
item 25) 톱레벨 클래스는 한 파일에 하나만 담으라 public class Main{ public static vod main(String[] args){ System.out.println(Utensil.NAME + Dessert.NAME); } } Main 은 Utensil 과 Dessert 클래스를 참조하는데 이 2개가 한파일에 정의되어있다고 가정하자. class Utensil{ static final String NAME = "pen"; } class Dessert{ static final String NAME = "sil"; } 우연히 같은 클래스를 가진 파일이 하나 더있게 되면 class Utensil{ static final String NAME = "pot"; } class Dessert{ static final String NAME = "p.. 더보기
item 18) 상속보다는 컴포지션을 사용하라 1. 상속 vs 컴포지션 상속 : 하위 클래스가 상위 클래스의 특성을 재정의한 것 (IS-A 관계) ( 여기서 상속은 클래스가 인터페이스를 구현하거나 인터페이스가 다른 인터페이스를 확장하는 개념 X ) 컴포지션 : 기존 클래스가 새로운 클래스의 구성요소가 되는 것 위임한다.(delegation, HAS-A 관계) - 상속은 캡슐화를 꺠트리고, 상위 클래스에 의존성 관계를 가지고 있기 때문에 상위클래스의 변화에 따라 하위클래스가 변경될 가능성이 있다. (OCP 규칙에 위반) - 메소드는 언제든지 재정의될 가능성이 있음 - 다른 패키지의 구체클래스를 상속하는 일은 위험하고, 같은 패키지 내에서라도 문제를 야기할수 있다. - 보통 IS-A 관계일떄 상속을 사용하고, HAS-A 관계일때 컴포지션을 사용하라고 하.. 더보기
item 13) clone 재정의는 주의해서 진행하라 1. Cloneable 인터페이스 /** * A class implements the Cloneable interface to * indicate to the {@link java.lang.Object#clone()} method that it * is legal for that method to make a * field-for-field copy of instances of that class. * * Invoking Object's clone method on an instance that does not implement the * Cloneable interface results in the exception * CloneNotSupportedException being thrown. * * B.. 더보기
item 12) toString을 항상 재정의하라 1. toString 함수란? toString 함수는 프로그래머가 객체를 잘 읽을수 있도록 대표적인 특성을 보여주는 함수이다. 하지만 Object의 toString 함수는 전혀 그런 특징을 보여주지 못하고 있다. Object의 toString 함수는 내부적으로 클래스 이름과 hashCode를 합한 문자열을 리턴하게 되어있는데 이것만으로는 객체의 특성을 파악하는데 부족하다. 프로그래머는 자신이 정의한 객체의 toString 함수를 재정의함으로써 프로그램 디버깅을 하기 더 쉽기 떄문에 이것을 재정의하는 것을 추천한다. public String toString() Returns a string representation of the object. In general, the toString method ret.. 더보기
item 11) equals를 재정의하려거든 hashCode도 재정의하라 1. hashCode 재정의의 필요성 다음 코드를 살펴보자 package item11; import java.util.HashSet; import java.util.Objects; import java.util.Set; public class PersonTest { static class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { //멤버변수 비교하는 equals만 재정의 if (this == o) return true; if (o == null || getClass() != o.ge.. 더보기
item 10) equals는 일반 규약을 지켜 재정의하라 1. Object.equals equals 메소드는 Object 클래스의 메소드로 객체의 동치성을 판별하기 위한 메소드이다. 특히 Collections 패키지의 Set , Map의 key 등에서 key의 동치성을 판별하기 위해 자주 사용된다. public boolean equals(Object obj) { return (this == obj); } 위 코드는 Object equals의 정의이다. 보다시피 객체의 레페런스 값을 비교한다. 그러므로 Object 클래스를 상속받은 클래스에서 equals를 재정의하지 않는다면 클래스 멤버변수가 같더라도 레퍼런스 값이 다르면 equals는 false를 리턴한다. 이러한 특징때문에 equals를 재정의하게 되는데 Collections의 Set, Map의 키 등은 전.. 더보기