반응형
전체 글

전체 글

    제네릭 - 규칙 29 형 안전 다형성 컨테이너를 쓰면 어떨지 따져보라

    제네릭은 Set이나 Map과 같이 하나 자료형을 가진 원소들을 담는 컨테이너에 가장 많이 사용된다. ex) Map, Set 그렇기 때문에 형인자는 컨테이너별로 고정되게 되어있다. 그러나 가끔 여러개의 자료형을 Map과 콜렉션에 컨테이너로서 사용하고 싶을 경우가 있을 것이다. 이는 다음과 같은 접근법을 사용하면 가능하다. 123456789101112131415161718192021222324252627282930import java.util.HashMap;import java.util.Map; public class Rule29 { public Map map = new HashMap(); public void putData(Class type, T instance) { map.put(type, instan..

    제네릭 - 규칙 28 한정적 와일드 카드를 써서 API 유연성을 높여라

    List와 같은 형인자 자료형은 불변 자료형이다. 이는 저번 규칙에서 보았듯이 List은 List의 어떠한 하위 자료형도 아니라는 것을 확인 하였다. 하지만 가끔은 불변 자료형보다 높은 유연성이 필요할 때가 있다. 예를 들어 일련의 원소들을 인자로 받아 차례로 스택에 집어 넣는 메서드가 있다고 가정하여 보자. 1234567891011121314package rule28; import java.util.Stack; public class Rule28 extends Stack{ private static final long serialVersionUID = 1L; public void pushAll(Iterable src) { for (E e : src) { push(e); } }}Colored by Col..

    제네릭 - 규칙 27 가능하면 제네릭 메서드로 만들 것

    클래스를 제네릭 하는 것도 많은 혜택을 볼 수 있지만 (규칙 26) 메소드를 제네렉 자료형으로 사용하는 것 또한 많은 혜택을 볼 수 있다. row type으로 사용하였을 경우에는 형안전성 문제때문에 다음과 같은 오류가 발생한다는 것을 저번에 규칙에서 확인을 했었다. 이런 문제를 형인자를 메서드에 추가로 선언하여 메서드를 구현하면 형안정성을 보장받을 수 있다. 출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1), 규칙27 인용.

    제네릭 - 규칙 26 가능하면 제네릭 자료형으로 만들 것

    클래스를 제네릭 자료형으로 제네릭화 해서 사용하면 많은 이점이 생긴다. 제네릭화 하는 과정의 첫 번째는 선언부에 형인자를 추가하는 것이다. 1public class Stackcs 하지만 형인자를 추가하다 보면, 배열에 E 자료형을 추가하려 할 때 문제가 발생한다. (25 규칙 확인) 이를 해결하기 위한 방법은 다음과 같다. 1. Object 배열을 만든 다음 제네릭 자료형으로 캐스팅 하는 것이다. => 하지만 이것은 다음과 같은 오류를 발생시킨다. => 만약 개발자 판단으로 형 안전성이 입증된다고 판단되는 경우 경고를 없애 주어야 한다. (규칙 24) 2. Object 배열로 사용하고 원소를 꺼내서 사용할 때 E로 캐스팅하여 사용한다. => 형안전성에 대한 개발자 판단이 완료되고 나면 @SuppressW..

    제네릭 - 규칙 25 배열 대신 리스트를 써라

    배열과 제네릭 자료형(List)의 차이 배열은 convariant 제네릭 자료형은 invariant 자료형이다. 차이 1. covariant - Sub[] 이 Super 의 하위자료형이라면 Sub[] 은 Super[]의 서브 타입이다. invariant Type1 Type2 List List 의 서브타입도 슈퍼타입도 아니다. 그렇기 때문에 List은 List의 서브타입 또는 슈퍼타입도 될 수 없다. 이런 이유로 제네릭 쪽이 배열보다 취약한 것 같지만 다음과 같은 문제를 보면 오히려 문제가 발생하는 부분은 배열이다. 12345678// 실행 중에 문제를 일으킴 (배열)Object[] objectArray = new Long[1];objectArray[0] = "babo ya";=> 컴파일시 문제는 없지만 ..

    제네릭 - 규칙 24 무점검 경고를 제거하라

    제네릭을 사용하다보면 다양한 원인으로 인해 컴파일러 경고 메시지를 보게된다. 이런 무점검 경고 가운데 상당수는 쉽게 없앨 수 있다. 예를 들면 다음과 같은 경우가 있다. 123456Set example = new HashSet(); // warning : unchecked conversion // 해결 방법Set example = new HashSet();cs 이런 예와 같은 무점검 경고는 가능하다면 없애야 typesafe(형안전성)을 보장할 수 있어 ClassCastException 발생을 방지할 수 있다. 형 안전성이 확실한 코드를 계속 warning 상태로 놔두게 되면 진짜 중요한 메시지를 놓칠 수 있기 때문에 만약 제거가 어려운 경고 메시지는 형 안전성이 확실하다고 생각될 경우에만 @Supress..

    제네릭 - 규칙 23 새 코드에는 무인자 제네릭 자료형을 사용하지 마라

    1. 용어 정리 - List와 같은 형식은 제네릭 클래스와 인터페이스로서 제네릭 자료형이라고 한다. - 제네릭 자료형은 raw Type인 무인자 자료형을 같는다. List의 raw type은 List이다. - raw type을 통해 사용하면 추후에 element를 사용할 시 캐스팅을 잘 해주어야 한다. 그렇기에 형 안정성 확보를 위해 컬렉션에 담길 객체의 자료형이 무엇인지 알려준다. 2. raw type vs generic type 1234567891011121314151617181920212223// 문제 1 (캐스팅 오류)List a = new ArrayList();a.add(generic); for (Iterator i = a.iterator(); i.hasNext();) { (Dv) i.next(..

    클래스와 인터페이스 - 규칙22 멤버 클래스는 가능하면 static으로 선언하라.

    중첩 클래스 (nested class)는 다른 클래스안에 선언된 클래스이다. 이런 중첩 클래스는 4가지 종류로 구성되어있다. 1. static member class 2. non-static member class 3. anonymous class 4. local class. 2 ~ 4번 클래스는 내부 클래스(inner class)이다. 상황별 중첩 클래스 사용 그럼 위에 출력한 4가지의 중첩 클래스의 적절한 사용 시기를 알아보자. 1. 정적 멤버 클래스 (static member class) - 정적 멤버 클래스는 바깥 클래스의 모든 멤버에 접근할 수 있다. (private 멤버 변수도 접근 가능) - 다른 정적 멤버와 동일하게 접근 권한 규칙을 따른다. - private static member cl..

    클래스와 인터페이스 - 규칙 21 전략을 표현하고 싶을 때는 함수 객체를 사용하라.

    호출 대상에 대해 어떠한 작업을 수행하는 것을 전략 패턴이라고 한다. 12345class StringCompare { public int compare (String s1, String s2) { return s1.length() - s2.length(); }}Colored by Color Scriptercs 두 개의 문자열을 받아서 비교하는 클래스를 사용할 수 있는 전략 패턴이다. 비교가 필요할 경우 매번 StringCompare 클래스를 생성하지 말고, 싱글톤 패턴을 정의하여 가져다가 사용하면 더욱 편리하다. 하지만 이 StringCompare 클래스의 경우 객체를 메서드에 전달하기 위해서는 인자의 자료형이 String이어야 한다. 따라서 Compareator 인터페이스를 정의 하여 이를 String..

    클래스와 인터페이스 - 규칙 20 태그 달린 클래스 대신 클래스 계층을 사용하라.

    클래스에 상황에 따라서 역할을 변경하는 태그 달린 클래스를 볼 수 있다. 예를 들어, 아래 유형과 같이 탈것을 나타내는 클래스는 어떤 형태로 사용하느냐에 따라서 자동차가 될수도, 자전거가 될 수도 있다. 12345678910111213141516171819202122232425class Vehicle { enum Type { CAR, BICYCLE }; final Type type; public Vehicle (double pedalCount) { this.type = Type.BICYCLE; } public Vehicle (double license, int sheetCount) { this.type = Type.CAR; } // 바퀴수를 반환하는 메서드 public int getWheelCount()..

반응형