티스토리 뷰
57 지역변수의 범위를 최소화하라
지역변수의 범위를 줄이는 가장 강력한 기법은 ‘가장 처음 쓰일 때 선언하기’다.
거의 모든 지역변수는 선언과 동시에 초기화해야 한다. 초기화에 필요한 정보가 충분하지 않다면 충분해질 때까지 선언을 미뤄야 한다.
*try-catch문은 이 규칙에서 예외다. 변수를 초기화하는 표현식에서 검사 예외를 던질 가능성이 있다면 try 블록 안에서 초기화해야 한다.
지역변수 범위를 최소화하는 마지막 방법은 메서드를 작게 유지하고 한 가지 기능에 집중하는 것이다.
반복문에서는 반복 변수의 범위가 반복문의 몸체, 그리고 for 키워드와 몸체 사이의 괄호 안으로 제한된다.
for (Element e : c) {
... // e로 무언가를 한다.
}
for (Iterator<Element> i = c.iterator(); i.hasNext(); ) {
Element e = i.next();
... // e와 i로 무언가를 한다.
}
for문의 지역변수의 범위를 최소화하는 또 다른 반복문 관용구다.
for (int i = 0, n = expensiveComputation(); i < n; i++) {
... // i로 무언가를 한다.
}
반복 여부를 결정짓는 변수 i의 한곗값을 변수 n에 저장하여, 반복 때마다 다시 계산해야 하는 비용을 없앴다.
59 라이브러리를 익히고 사용하라
표준 라이브러리를 사용하면 그 코드를 작성한 전문가의 지식과 여러분보다 앞서 사용한 다른 프로그래머들의 경험을 활용할 수 있다
표준 라이브러리를 쓰는 두 번째 이점은 핵심적인 일과 크게 관련 없는 문제를 해결하느라 시간을 허비하지 않아도 된다는 것이다.
세 번째 이점은 따로 노력하지 않아도 성능이 지속해서 개선된다는 점이다.
네 번째 이점은 기능이 점점 많아진다는 것이다.
마지막 이점은 여러분이 작성한 코드가 많은 사람에게 낯익은 코드가 된다는 것이다.
자바 프로그래머라면 적어도 java.lang, java.util, java.io와 그 하위 패키지들에는 익숙해져야 한다.
java.util.concurrent의 동시성 기능도 알아두면 큰 도움이 된다
60 정확한 답이 필요하다면 float와 double은 피하라
float와 double 타입은 이진 부동소수점 연산에 쓰이며, 넓은 범위의 수를 빠르게 정밀한 ‘근사치’로 계산하도록 설계되었기 때문에 정확한 결과가 필요할 때는 사용하면 안 된다.
특히 금융 관련 계산과는 맞지 않는다. 금융 계산에는 BigDecimal, int 혹은 long을 사용해야 한다.
61 박싱된 기본 타입보다는 기본 타입을 사용하라
자바의 데이터 타입은 크게 두 가지로 나눌 수 있다.
- int, double, boolean같은 기본 타입
- String, List 같은 참조 타입
각각의 기본 타입에는 대응하는 참조 타입이 하나씩 있으며, 이를 박싱된 기본 타입이라고 한다.
*int, double, boolean에 대응하는 박싱된 기본 타입은 Integer, Double, Boolean이다.
오토박싱과 오토언박싱 덕분에 두 타입을 크게 구분하지 않고 사용할 수는 있지만 어떤 타입을 사용하는지는 상당히 중요하다.
기본 타입과 박싱된 기본 타입의 주된 차이는 크게 세 가지다.
- 기본 타입은 값만 가지고 있으나, 박싱된 기본 타입은 값에 더해 식별성(identity)이란 속성을 갖는다. (박싱된 기본 타입의 두 인스턴스는 값이 같아도 서도 다르다고 식별될 수 있다.)
- 본 타입의 값은 언제나 유효하나, 박싱된 기본 타입은 유효하지 않은 값, 즉 null을 가질 수 있다.
- 기본 타입이 박싱된 기본 타입보다 시간과 메모리 사용면에서 더 효율적이다.
박싱된 기본 타입에 == 연산자를 사용하면 오류가 일어난다. == 연산자를 사용하려면 박싱된 타입을 기본타입으로 저장하자.
public class Unbelievable {
static Integer i;
public static void main(String[] args) {
if (i == 42) System.out.println("믿을 수 없군!");
}
}
i == 42를 검사할 때 NullPointerException이 발생한다. 기본 타입과 박싱된 기본 타입을 혼용한 연산에서는 박싱된 기본 타입의 박싱이 자동으로 풀린다.
63 문자열 연결을 느리니 주의하라
문자열 연결 연산자로 문자열 n개를 잇는 시간은 n^2에 비례한다. 성능을 포기하고 싶지 않다면 String 대신 StringBuilder를 사용하자.
문자열 연결자(+) 대신 StringBuilder의 append 메서드를 사용하면 된다.
64 객체는 인터페이스를 사용해 참조하라
적잡한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라.
Set<Son> sonSet = new LinkedHashSet<>;
위 코드는 인터페이스를 타입으로 선언했지만 아래 코드는 클래스를 타입으로 사용했다.
LinkedHashSet<Son> sonSet = new LinkedHashSet<>();
인터페이스를 타입으로 사용하는 습관을 길러두면 프로그램이 훨씬 유연해질 것이다.
적합한 인터페이스가 없다면 당연히 클래스로 참조해야 한다. (String, BigInteger ...)
적합한 인터페이스가 없다면 클래스의 계층구조 중 필요한 기능을 만족하는 가장 덜 구체적인(상위의) 클래스를 타입으로 사용하자.
65 리플렉션보다는 인터페이스를 사용하라
리플렉션 기능(java.lang.reflect)을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다.
그 클래스의 생성자, 메서드, 필드에 해당하는 Constructor, Method, Field 인스턴스를 가져올 수 있으며 해당 인스턴스를 통해 각각에 연결된 실제 생성자, 메서드, 필드를 조작할 수도 있다.
그러나 리플렉션엔 단점이 존재한다.
- 컴파일타임 타입 검사가 주는 이점을 하나도 누릴 수 없다.
- 리플렉션을 이용하면 코드가 지저분하고 장황해진다.
- 성능이 떨어진다.
리플렉션은 아주 제한된 형태로만 사용해야 그 단점을 피하고 이점만 취할 수 있다.
되도록 리플렉션은 인스턴스 생성에만 쓰고, 이렇게 만든 인스턴스는 인터페이스나 상위 클래스로 참조해 사용하자.
66 네이티브 메서드는 신중히 사용하라
전통적으로 네이티브 메서드의 주요 쓰임은 다음 세 가지다.
- 레지스트리 같은 플랫폼 특화 기능을 사용한다.
- 네이티브 코드로 작성된 기존 라이브러리를 사용한다.(ex 레거시 데이터를 사용하는 레거시 라이브러리)
- 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 작성한다.
성능을 개선할 목적으로 네이티브 메서드를 사용하는 것은 거의 권장하지 않는다.
67 최적화는 신중히 하라
성능 때문에 견고한 구조를 희생하지 말자. 빠른 프로그램보다는 좋은 프로그램을 작성하라.
좋은 프로그램은 정보 은닉 원칙을 따르므로 개별 구성요소의 내부를 독립적으로 설계할 수 있다.
따라서 시스템의 나머지에 영향을 주지 않고도 각 요소를 다시 설계할 수 있다.
프로그램을 완성할 때까지 성능 문제를 무시하라는 뜻이 아니다. 아키텍처의 결함이 성능을 제한하는 상황이라면 시스템 전체를 다시 작성하지 않고는 해결하기 불가능할 수 있다.
따라서 설계 단계에서 성능을 염두하기 위해 다음 4가지 사항을 고려해보자.
- 성능을 제한하는 설계를 피하라.
- API를 설계할 때 성능에 주는 영향을 고려하라.
- 성능을 위해 API를 왜곡하는 건 매우 안 좋은 생각이다.
신중하게 설계하여 깨끗하고 명확하고 멋진 구조를 갖춘 프로그램을 완성한 다음에야 최적화를 고려해볼 차례가 된다. 물론 성능에 만족하지 못할 경우에 한정된다.
68 일반적으로 통용되는 명명 규칙을 따르라
자바의 명명 규칙은 크게 철자와 문법으로 나뉜다.
철자 규칙은 클래스, 인터페이스, 메서드, 필드, 타입 변수의 이름을 다룬다.
*이 규칙들은 특별한 이유가 없는 한 반드시 따라야 한다.
- 패키지와 모듈 이름은 각 요소를 점(.)으로 구분하여 계층적으로 짓는다.
- 요소들은 모두 소문자 알파벳 혹은 숫자로 이뤄진다.
- 조직 바깥에서도 사용될 패키지라면 조직의 인터넷 도메인 이름을 역순으로 사용한다. ex → edu.cmu, com.google, org.eff *표준 라이브러리와 선택적 패키지들은 각각 java와 javax로 시작한다.
- 패키지 이름의 나머지는 해당 패키지를 설명하는 하나 이상의 요소로 이뤄진다.
- 각 요소는 일반적으로 8자 이하의 짧은 단어로 한다. *utilities보다는 util처럼 의미가 통하는 약어를 사용하자.
- 클래스와 인터페이스의 이름은 하나 이상의 단어로 이뤄지며 각 단어는 대문자로 시작한다.
- 여러 단어의 척 글자만 딴 약자나 max, min처럼 널리 통용되는 줄임말을 제외하고는 단어를 줄여 쓰지 않도록 한다.
- 약자의 경우 첫 글자만 대문자로 할지 전체를 대문자로 할지는 논란이 있지만 첫 글자만 대문자로 하는 쪽이 많다.
- 메서드와 필드 이름은 첫 글자를 소문자로 쓴다는 점을 제외하면 클래스 명명 규칙과 동일하다. ex → remove, ensureCapacity
- 단, 상수 필드는 구성하는 단어 모두 대문자로 쓰이며 단어 사이는 밑줄로 구분한다.(MAX_VALUE 등) *상수 필드는 값이 불변인 static final 필드를 말한다.
- 지역 변수는 사용되는 문맥에서 의미를 유추할 수 있기 때문에 약어를 사용해도 무방하다. ex → i, denom, houseNum
- 타입 매개변수 이름은 보통 한 문자로 표현한다.
- 임의의 타입 → T (Type)
- 컬렉션 원소의 타입 → E (Element)
- 맵의 키와 값 → K, V (Key, Value)
- 예외 → x (eXception)
- 메서드의 반환 타입 → R (Return)
- 타입의 시퀀스에는 T, U, V 혹은 T1, T2, T3을 사용한다.
- 객체를 생성할 수 있는 클래스(열거 타입 포함)의 이름은 보통 단수나 명사나 명사구를 사용한다. ex → Thread, PriorityQueue, ChessPiece
- 객체를 생성할 수 없는 클래스의 이름은 보통 복수형 명사로 짓는다 ex → Collectors, Collections
- 인터페이스 이름은 클래스와 똑같이 짓거나 able 혹은 iable로 끝나는 형용사로 짓는다. ex → Collection, Comparator ex → Runnable, Iterable, Accessible
- 에너테이션은 다양하게 활용되기 때문에 지배적인 규칙이 없이 명사, 동사, 전치사, 형용사가 두루 쓰인다.
- 메서드의 이름은 동사나 목적어를 포함한 동사구로 짓는다. ex → append, drawImage
- boolean을 반환하는 메서드라면 보통 is나 has로 시작하고 명사, 명사구 혹은 형용사로 기능하는 단어나 구로 끝나도록 짓는다. ex → isDigit, isProbablePrime, isEmpty, isEnabled, hasSiblings
- 반환 타입이 boolean이 아니거나 해당 인스턴스의 속성을 반환하는 메서드의 이름은 보통 명사, 명사구, 혹은 get으로 시작하는 동사구로 짓는다 ex → size, hashCode, getTime
- 객체의 타입을 바꿔서, 다른 타입의 또 다른 객체를 반환하는 인스턴스 메서드의 이름은 보통 toType 형태로 짓는다 ex → toString, toArray
- 객체의 내용을 다른 뷰로 보여주는 메서드의 이름은 asType 형태로 짓는다 ex → asList
- 객체의 값을 기본 타입 값으로 반환하는 메서드의 이름은 보통 typeValue 형태로 짓는다 ex → intValue
- 정적 팩터리의 이름은 다양하지만 from, of, valueOf, instance, getInstance, newInstance, getType, newType을 주로 사용한다.
'프로그래밍 > 책' 카테고리의 다른 글
[이펙티브 자바, Effeective Java] 10장 예외 (0) | 2022.02.04 |
---|---|
[이펙티브 자바, Effeective Java] 8장 메서드 (0) | 2022.01.19 |
[이펙티브 자바, Effeective Java] 7장 람다와 스트림 (0) | 2022.01.04 |
[이펙티브 자바, Effeective Java] 6장 열거 타입과 어노테이션 (0) | 2021.12.28 |
[이펙티브 자바, Effeective Java] 5장 제네릭 (0) | 2021.12.22 |
- Total
- Today
- Yesterday
- 오라클 계정 오류
- 토이프로젝트 회고
- CI/CD
- nginx 내장톰캣 설정
- nginx 내장톰캣 연결
- spring boot jenkins
- GitHub
- 스프링부트 젠킨스
- webhook
- oracle.jdbc.driver.T4CConnection.isValid(I)Z
- jenkins webhook
- 젠킨스 자동 배포
- spring boot
- 국비 프로젝트
- github webhook
- java.lang.AbstractMethodError
- 스프링부트 자동배포
- slack
- oracle
- HTML
- springboot
- nginx to tomcat
- nginx 톰캣 설정
- nginx to springboot tomcat
- github webhook jenkins
- 깃허브 웹훅 젠킨스
- 젠킨스 웹훅
- nginx to 내장톰캣
- springboot jpa
- 오라클
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |