1.1. Basical Theory
1.1.1. 매개변수는 참조가 아니라 값으로 넘겨준다.
- 자바에서 모든 객체는 객체참조로 접근한다.
- 흔히들 자바가 매개변수를 참조로 넘겨준다고 생각하는 오류를 범한다. (Call By Reference)
- 그러나 실은 모든 변수는 참조가 아닌 값으로 넘겨준다. (Call By Value)
- 참고 : 메소드에 객체를 넘기는 경우 참조하고 있는 객체 변수의 값을 넘겨 주기 때문에 참조로 넘겨주는 것 처럼 보인다.
1.1.2. 상수나 상수객체 참조를 만들고자 할 경우 final을 사용하라.
- 데이터나 객체참조를 항상 같은값으로 유지하고자 한다면 final을 써야한다.
- final은 객체참조만 상수로 만들어 변경 못하게 하지 객체 자체를 final로 만들지 않음을 주의 하라.
final Test a1 = new Test();
a1 = new Test(); // 오류 발생
Test a2 = new Test(); // 정상 수행
Test t3 = t1; // 정상 수행
t3 = t2; // 정상 수행
즉, 결론적으로 파이널로 지정된 a1에만 다른 객체변수를 지정할 수 없다. 즉, 변수 자체에 대한 final이 수행된것이며, 객체에 final이 적용되지 않았다.
1.1.3. 모든 non-static 메소드는 자동적으로 오버라이드(overrride)된다.
- 기본적으로 non-static메소드는 서브클래스(subclass)가 오버라이드 한다.
- final을 써서 자동 오버라이드를 막을 수 있다.
1.1.4. 배열과 Vector중 고를 때 주의하라
- 배열과 Vector은 일반적으로 사용하는 저장 클래스이다.
- 그들의 기능과 틀성을 사용하기 전에 알아두라.
1.1.5. instanceof 보다 다형성(polymorphism)이 낫다.
- 많은경우 다형상으로 instanceof를 제거할 수 있다.
- 다형성을 쓰는 것이 더 알기 쉽고 확장 가능하고 유지하기 좋은 코드가 된다.
1.1.6. 어쩔 수 없는 경우에만 instanceof를 써라.
- instanceof를 피할 수 없는 경우가 있다.
- 써야하는 상황을 잘 알아두어야 한다.
1.1.7. 더 이상 쓰지 않는다면 객체 참조를 null로 두어라
- 메모리 문제를 무시하지 마라.
- 가비지 컬렉션이 쓸만하지만 코드가 어떻게 메모리를 잡아 먹는지 여전히 신경을 써야 한다.
- 가비지 컬렉션이 메모리를 어떻게 쓰는지 상세하게 알고 있으면 언제 객체 참조를 null로 두어 더 효율적인 코드가 되는지 알 수 있다.
1.2. 객체와 동일성
1.2.1. 참조와 원시타입(primitive type)을 잘 가려 써라.
- 자바는 객체지향적이지만 거기서 다루는 모든 것이 객체인 것은 아니다.
- 참조와 원시타입사이의 차이를 이해하고 JVM속에서 나타나는 모습을 이해해야 둘 중 현명하게 선택할 수 있다.
1.2.2. ==과 equals을 가려써라
- == 을 써서 원시타입의 데이터들이 같은지 비교하거나 객체참조를 비교하라.
- 값을 비교하거나 의미적 비교를 할때는 equals를 써라.
1.2.3. equals의 기본 구현을 믿지 마라
- equals가 자동적으로 맞게 구현되었으리라고 간주하지 마라.
- java.lang.Object에는 equals메소드가 있는데 대부분의 경우 원하는 비교를 하지 못한다.
1.2.4. equals 메소드를 사리에 맞게 구현하라
- 메모리상에서 같은 공간을 차지하지 않아도 두 객체가 논리적으로 같다고 판단하는 equals메소드를 만들어라.
1.2.5. equals 메소드 구현에서 getClass를 선호하라.
- 같은 클래스의 객체만 equal할 수 있게 허락하는 것이 간단하고 깨끗한 해법이며 equals메소드를 정확하게 구현하는 방법이 된다.
1.2.6. 기반 클래스(base class)의 super.equals를 호출하라
- java.lang.Object말고 다른 기반 클래스가 equals메소드를 구현했다면 파생된 클래스에서 super.equals를 호출하라.
1.2.7. equals메소드 구현에서 instanceof를 신중하게 사용하라.
- 파생된 클래스의 객체와 그 기반 클래스의 객체를 동일하게 두고 싶으면 equals메소드에서 instanceof를 사용하라.
- 하지만 이 방법을 쓰기 전에 문제점을 생각해보라.
1.2.8. equals메소들르 구현할 때 이러한 규칙들을 따르라.
- equals메소드를 쓰는 것은 한방에 할 수 있는 일이 아니다. 규칙을 따르라.
1.3. 예외 처리
1.3.1. 예외가 처리되는 흐름을 알아두자
- 예외 처리흐름의 세부적인 사항에 익숙해져라.
- 미묘한 문제점을 알면 미연에 문제들을 피할 수 있다.
1.3.2. 예외를 무시하지 마라.
- 예외를 잡지 않으면 예외가 발생한 쓰레드는 끝난다.
- 예외는 에러를 나타내는 것이라 무시하면 안된다.
1.3.3. 예외를 숨기지 마라.
- 전에 던져진 예외를 처리하는 동안 catch나 finally블록에서 예외를 던지더라도 그 예외는 가려진다.
- 이 상황을 제대로 다루려면 따로 코드를 써야하고 예외를 부른 모든 메소드에게 리턴해야 한다.
1.3.4. throws 문의 단점을 생각하라.
- 메소드의 throws문에 예외를 더하는 것은 그것을 호출하는 모든 메소드에 영향을 미친다.
1.3.5. throws 문을 구체적이고 전체적으로 파악하라.
- 메소드의 throws문은 파생되는 (derived)예외타입까지 포함해서 전파하는 모든 예외를 열거해야 한다.
1.3.6. 시스템 자원이 새나가는 것을 막기위해 finally를 써라.
- 비메모리 자원(non-memory resources)을 무시하지 마라.
- 가비지 멀력터는 그걸 환원하지 않을 것이다.
- finally를 써서 비메모리 자원을 놓아주도록 하라.
=== try 블럭에서 리턴하지 마라.===
- try블럭에서 리턴하지 마라. 왜냐하면 메소드가 즉각 리턴하지 않고 뜸을 들일 수 있기 때문이다.
- finally블럭이 있다면 리턴 값을 변경해 버릴 수 도 있다.
1.3.7. try/catch를 반목문 밖에 두라.
- 예외를 다루는 반목문을 코딩할 때, try/catch 블럭을 반복문 밖에 두라.
- 그러면 코드가 더 빨라 질 수 있다.
- 단, 반복문을 사용하다 시스템이 죽을 수 있다는 것을 염두에 두라.
1.3.8. 제어흐름에 예외를 쓰지 마라.
- 에러조건을 다룰 때만 예외를 써라.
- 코드의 흐름이 더 알기 쉽고 표준적 언어 흐름구조로 더 효과적으로 표현된다.
1.3.9. 에러조건이라고 모두 예외로 처리하지는 마라.
- 예상할 수 없는 동작 조건에 대해서 예외를 써라.
- 예상할 수 있는 동작은 리턴 코드로 다룰 수 있다.
1.3.10. 생상자에서 예외를 던져라
- 비록 생성자는 메소드가 아니고 리턴 값도 없지만 생성하다 실패할 수 있다.
- 그럴때 예외를 던져라
1.3.11. 예외상황을 알리기 전에 객체를 올바른 상태로 복구하라.
- 예외를 던지는 것은 쉽다.
- 힘든 부분은 예외를 던지기 전에 피해를 최소화 하는 것이다.
1.4. 성능
1.4.1. 처음에는 설계, 자료구조, 알고리즘에 집중하라
- 성능을 가장 높이는 방법은 언어 독립적 기법으로 디자인하는 것과 좋은 알고리즘을 쓰는 것이다.
- 초점을 우선 거기에 맞춰라.
1.4.2. 컴파일러 최적화옵션에 의지하지 말라.
- 자바 컴파일러가 만드는 코드는 전형적으로 직접 쓴느 코드보다 나을 게 없다.
- 컴파일러가 소스코드를 최적화하게 하지마라.
1.4.3. 런타임 코드 최적화를 이해하라.
- 자바 성능에 관계된 노력의 대부분이 런타임 최적화에 집중되어 있다.
- 이 접근에는 장단점이 있다.
1.4.4. 문자열을 이을 때는(concatenation) String보다 StringBuffer를 써라.
-
문자열을 이어 붙일 때는 StringBuffer가 String보다 훨씬 빠르다.
1.4.5. 객체생성 비용을 최소화 하라.
- 객체생성은 많은 객체지향시스템에서 큰 비용이 든다.
- 객체생성을 빠르게 하는 방법과 생성비용을 이해하면 빠른 코드를 만들 수 있다.
1.4.6. 쓰지않은 객체를 막아라.
- 필요할 때까지는 객체를 생성하지 마라. 쓸데없이 생성하는 객체는 코드를 느리게 만든다.
1.4.7. 동기화를 최소화 하라.
- synchronized 메소드나 블럭을 선언하는 것은 성능을 상당히 깍아 내린다.
- 필요할 때만 동기화 하라.
1.4.8. 가능하면 스택변수를 써라
- 스택변수는 더 효과적 바이트코드 명령문(instruction)들을 만들어낸다.
- 그래서 반복문에서 static변수나 인스턴스 변수에 접근할 때 잠깐 스택변수에 담아 코드를 빠르게 할 수 있다.
1.4.9. 메소드를 인라인하려면(inlining) static이나 final, private으로 선언하라.
- 모든 static 변수와 인스턴스 변수는 자동적으로 기본값이 배정되기 때문에 한번 더 배정할 필요는 없다.
1.4.10. 인스턴스 변수를 딱 한번만 초기화 하라.
- 모든 static변수와 인스턴스 변수는 자동적으로 기본값이 배정되기 때문에 한번 더 배정할 필요는 없다.
1.4.11. 원시타입(primitive type)을 써서 코드를 작고 빠르게 만들어라.
- 원시타입을 쓰면 원시 래퍼클래스(wrapper class)객체보다 작고 빠른 코드가 된다.
1.4.12. Vector 에서 원소들을 뽑아내어 쓸 때 Enumeration나 Iterator를 쓰지마라.
- Vector를 쭉 훑을 때 Enumeration이나 Iterator대신에 get메소드를 써라.
- 이렇게 하면 메소드 호출이 거의 없어지고 빠른 코드가 된다.
1.4.13. 배열을 복사할 때 System.arraycopy를 써라.
- System.arraycopy의 이점을 활용하라.
- 이것은 native메소드로 구현되어 있고 다른 것보다 빠르다.
1.4.14. Vector나 ArrayList보다 배열을 써라.
- 가능하다면 배열을 써라.
-
Vector에 있는 기능이 필요하고 동기화는 필요없다면 ArrayList를 써라.
1.4.15. 되도록이면 객체를 재사용 하라.
- 새로 만드는 것보다 기존의 객체를 재사용하는 것이 거읜 언제나 싸다.
1.4.16. 미루었다가 계산하라.(lazy evaluation)
- 되도록이면 비싼 계산을 줄여라. lazy evaluation을 써서, 하지도 않는 일을 피하라.
1.4.17. 소스 코드를 손수 최적화 하라.
- 자바 컴파일러가 최적화를 거의 안 하기 때문에 손수 자신의 코드를 최적화 하라.
1.4.18. native code로 컴파일 하라.
- native code로 컴파일 하는 것이 전형적으로 빠른 실행코드를 낸다.
- 하지만 다양한 native솔루션들로 바꾸는 것을 생각해 봐야 한다.
'Architect' 카테고리의 다른 글
스크럼 회의 (0) | 2009.09.29 |
---|---|
Eclipse plugins for Maven (0) | 2008.10.23 |
리스크관리 개요 (0) | 2008.07.17 |
Loosed Coupling 을 잘 모르는 사람. (0) | 2008.07.02 |
Ship It - 부록 소스코드 관리 도구 - (0) | 2008.06.27 |