Programming/Java 24

[Effective Java] item28 - 배열보다는 리스트를 사용하라

배열보다는 리스트를 사용하라!앞 아이템에서 살짝 설명했는데, 배열은 공변성을 갖고 있고 리스트는 그렇지 않다. 다시 말해서, sub와 super가 상/하위 클래스 관계라면, sub[]는 super[]의 하위 타입이 되는 것이다.Object[] arr = new Long[140]; arr[0] = "들어갈까?"; // 들어갈리가 없다.'문법'상 틀린 코드는 아니지만, 상식적으로 들어갈리가 없다는걸 알 것이다. 이런 경우 런타임시 ArrayStoreException이 발생하는데, 이는 런타임 과정에서 자신이 담기로 한 원소의 타입을 체킹해서 예외를 반환하는 것이다.앞서 제네릭은 공변성을 갖고 있지 않다고 했는데, 따라서List list = new ArrayList(); list.add("들어갈까?");의 경..

Programming/Java 2021.03.24

[Effective Java] item27 - 비검사 경고를 제거하라

비검사 경고를 제거하라! 제네릭을 사용하기 시작한 순간 컴파일러 경고와 친구가 될 것이다... 특히 제네릭에 익숙해지지 않으면 온갖 기묘한 경고들을 마주하게 될 것이다. 요즘은 인텔리제이같은 훌륭한 IDE가 있어서 수많은 경고를 미리 체크해주지만, 만약에 그런 IDE를 쓰지 않으면 javac 명령줄 인수에 -Xlint:unchecked를 붙여주자. (비검사 경고!) Set exaltation = new HashSet(); 이런 코드가 있다고 하자. 딱 봐도 문제가 있는걸 깨달을 수 있을 것이다. 위에서 명시한 Xlint 옵션을 붙여주면 컴파일러에서 어떤식으로 수정해야 하는지 제시해주고, 그거에 맞춰 수정해주면 된다. (사실 IDE가 좋으면 알아서 고쳐준다.) 자바7 부터는 다이아몬드 연산자를 활용해 컴파..

Programming/Java 2021.03.24

[Effective Java] item26 - 로타입은 사용하지 말라

로타입은 사용하지 말라! 제네릭이 뭐였더라? 클래스와 인터페이스 선언 과정에서 타입 매개변수를 사용하게 된다면, 우리는 그것을 제네릭 클래스/인터페이스라고 한다. 각각의 제네릭 타입은 일련의 매개변수화 타입을 정의하고, 이어서 괄호 안에 실제 타입 매개변수들을 나열한다. (ex. list: 원소의 타입이 String인 리스트를 뜻하는 매개변수화 입이고, 여기서 String은 정규타입 매개변수 E에 해댕하는 실제 타입 매개변수) 동시에, 제네릭 타입을 하나 정의하면 그에 따른 로 타입 (Law Type)도 함께 정의되는데, 이는 타입 매개변수를 전혀 사용하지 않은 제네릭 타입이다. 즉, List를 선언했으면, 그에 따른 로 타입은 List가 되는 것이다. 왜 이런게 필요한걸까? 이유는 제네릭이 도입되기 전..

Programming/Java 2021.03.24

[Effective Java] item25 - 톱레벨 클래스는 한 파일에 하나만 담으라

톱레벨 클래스는 한 파일에 하나만 담으라!사실 일반적으로는 톱레벨 클래스를 한 파일에 두 개 이상 담는 일이 거의 없다. 특히 어지간한 IDE에서는 절대로 그런짓을 못 하게 한다. 왜 그럴까?이 책에 따르면, "한 클래스를 여러 가지로 정의할 수 있으며, 컴파일하는 순서에 따라 어떤 것을 사용하는지 달라진다." 라고 적혀있다. 직접 코드를 짜보자.// Driver.java public class Driver { public static void main(String[] args) { System.out.println(MainMenu.NAME + SideMenu.NAME); } } // MainMenu.java class MainMenu { static final String NAME = "Chicken"..

Programming/Java 2021.03.24

[Effective Java] item24 - 멤버 클래스는 되도록 static으로 구성하라!

멤버 클래스는 되도록 static으로 구성하라!가끔 다른 코드를 보면 클래스 내에 정의된 중첩 클래스 (Nested Class)가 있을때가 많다. 이 경우 중첩 클래스는 반드시 자신을 감싼 바로 바깥 클래스에서만 사용할 수 있다.이 책에서는 중첩 클래스의 종류를 정적 멤버 클래스, (비정적) 멤버 클래스, 익명 클래스, 지역 클래스로 분류하고 있는데, 이번 아이템에서는 각각의 중첩 클래스에 대해 맛 볼 것이다.정적 멤버 클래스는 다른 클래스 내부에 선언되고, 바깥 클래스의 private에 접근할 수 있는 점만 빼면 일반 클래스와 동일한 역할을 하고, 흔히 바깥 클래스와 함께 쓰일 때만 유용한 public 도우미로 사용된다. public으로 사용하기 때문에 Calculator.Operation.PLUS 같..

Programming/Java 2021.03.16

[Effective Java] item23 - 태그 달린 클래스보다는 클래스 계층구조를 활용하라!

태그 달린 클래스보다는 클래스 계층구조를 활용하라!사실 이 부분은 별로 와닿지 않는 부분이긴 하다. '당연한거 아닌가?' 싶긴 한데... 그래도 일단 정리해보았다.클래스에 두가지 의미가 있는 요상한 경우가 있다고 해보자. 이번엔 영화관 예시를 들어보자. 이 영화관 멤버십 제도는 일반/VIP로 나뉜다고 하자. VIP를 유지하기 위해선 1년간의 영화 관람 기록을 기반으로 마일리지를 계산해서 판단하지만, 일반이 VIP로 올라가기 위해 1년간 영화를 꾸준히 보는건 어려우니 한달간 관람한 영화를 기준으로 마일리지를 계산해서, 조건이 되면 3개월 후 올려준다고 하자.이걸 하나의 클래스로 묶어버리면, 다음과 같이 될 것이다.public class MemberShip { enum MemberClass { NORMAL,..

Programming/Java 2021.03.16

[Effective Java] item22 - 인터페이스는 타입을 정의하는 용도로만 사용하라!

인터페이스는 타입을 정의하는 용도로만 사용하라!계속해서 인터페이스 이야기가 나온다. 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할을 한다고 한다. 즉, 클래스가 특정 인터페이스를 구현하면, 클라이언트로부터 자신의 인스턴스로 할 수 있는 것을 알려주는 것이다. 그리고, 인터페이스는 오직 이 용도로 사용해야 한다.다만 가끔 일부 사람들이 상수 인터페이스라는 것을 사용하는데, 이는 오직 static final 필드로만 가득 찬 인터페이스이다. 그러나 명시해야 할 점은, 우리가 클래스 내부에서 사용하는 상수는 외부 인터페이스의 역할이 아니다. 어찌보면 내부 API 구현의 일부를 바깥에 공개해버리는 꼴이 된다! 게다가 상황에 따라 해당 상수를 사용하지 않더라도 컴파일 과정에서의 하위호환을 위해 해당..

Programming/Java 2021.03.16

[Effective Java] item20 - 추상 클래스보다는 인터페이스를 우선하라!

추상 클래스보다는 인터페이스를 우선하라!자바가 기본적으로 제공하는 다중 구현 메커니즘은 인터페이스와 추상 클래스로 나뉜다. 일반적인 자바 입문서를 보면 인터페이스는 메소드 구현이 불가하다고 나와있지만 정말일까? 사실 인터페이스도 default method를 갖고 있다!public interface Calculator { public int plus(int x, int y); public int minus(int x, int y); default int defaultPlus(int x, int y) { return x + y; } public static int staticMinus(int x, int y) { return x - y; } }추상 클래스의 경우 extends를 사용해야 하고, 인터페이스의 ..

Programming/Java 2021.03.08

[Effective Java] item19 - 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라!

상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라!개발을 할 때 상속이 편리한 친구이긴 하지만, 외부 클래스를 상속하는 과정에서 발생하는 문제들도 분명 있다. 그렇기에 상속을 할 가능성을 조금이라도 열어놓는다면 문서화를 해 두는 것을 권장한다.일반적으로 상속을 하면 가장 먼저 하는 것 중에 하나가 메소드 재정의일 것이다. 그러나 상속을 하는 사람들이 이 메소드의 구체적인 역할이 무엇인지 판단해야 하므로, 상속용 클래스는 재정의할 수 있는 메소드들을 내부적으로 어떻게 이용하는지 문서로 남길 필요가 있다. 구체적으로 어떤 순서로 내부 과정이 이뤄지는지, 각각의 결과가 어떤 결과를 만들어내는지 까지 작성하면 좋다.자바 API 문서의 메소드 설명을 보면, 가끔 특이한 문구가 붙어있다.Imple..

Programming/Java 2021.03.08

[Effective Java] item15 - 클래스와 멤버의 접근 권한을 최소화하라.

클래스와 멤버의 접근 권한을 최소화하라! 객체지향의 요소를 떠올리면, 캡슐화 (Encapsulation) 이라는 말이 있다. 해당 요소의 의미는 프로그램 내 같은 기능을 목적으로 작성된 코드를 모아서 보이지 않게 숨기는 것을 의미한다. 그런데 왜 캡슐화를 해야할까? 객체지향적인 이야기이긴 하지만, 몇 가지 장점을 생각해보자. 여러 컴포넌트를 병렬로 개발할 수 있기 때문에 개발 속도를 향상시킨다. 컴포넌트를 변경할 수 있고, 특정 컴포넌트를 분리해서 디버깅 할 수 있다. 다른 컴포넌트와 분리되어 있는 만큼, 성능 최적화를 위해선 특정 컴포넌트만 떼어서 최적화 하기에도 편하다. 독자적으로 동작하는 컴포넌트를 개발했으면, 해당 컴포넌트를 다른 프로젝트에서도 사용할 수 있기 때문에 재사용성이 올라간다. 시스템을..

Programming/Java 2021.02.18