철자 규칙 패키지, 클래스, 인터페이스, 메서드, 필드, 타입 변수의 이름을 다룸 특별한 이유가 없는 한 따라야함 → 어기면 코드를 읽기 어렵고 유지보수하기 어려움 1) 패키지와 모듈 각 요소를 점(.)으로 구분하여 계층적으로 짓기 요소들은 모두 소문자 알파벳 혹은 드물게 숫자로 이루어짐 조직의 인터넷 도메인 이름을 역순으로 사용 ex) com.google, org.eff 예외로 표준 라이브러리는 java, 선택 패키지들은 javax로 시작 패키지 이름의 나머지는 해당 패키지를 설명하는 하나 이상의 요소로 이루어짐 각 요소는 8자 이하의 짧은 단어로 (한 단어 혹은 약어) 2) 클래스와 인터페이스 하나 이상의 단어로 이루어짐, 각 단어는 대문자로 시작 ex) List 여러 단어의 첫글자만 딴 약자나 ma..
최적화는 오히려 좋은 결과보다 해로운 결과로 이어지기 쉽다. 빠르지도 않고 제대로 동작하지도 않고 수정하긴 어려운 소프트웨어가 탄생할 수 있다. 빠른 프로그램보다는 좋은 프로그램을 작성하라 성능 때문에 견고한 구조를 희생하지 말자. (견고한 구조 - 내부 응집성이 높고 외부와 결합성이 낮은) 좋은 프로그램은 정보 은닉 원칙을 따라 개별 컴포넌트의 내부가 독립적으로 설계됨 → 나머지에 영향 주지않고도 각 요소를 재설계 가능 [아이템 15] 완성된 아키텍처의 결함이 성능을 제한하는 상황이라면 시스템 전체를 작성해야 해결 할 수 있기 때문에 설계 단계에서 성능을 반드시 염두에 두자. 성능을 제한하는 설계를 피하라 완성 후 변경하기 가장 어려운 설계 요소는 컴포넌트끼리, 또는 외부 시스템과의 소통 방식 ex) ..
자바 네이티브 인터페이스 (Java Native Interface, JNI) 자바 프로그램이 네이티브 메서드를 호출하는 기술 네이티브 메서드 : C나 C++ 같은 네이티브 프로그래밍 언어로 작성한 메서드 네이티브 메서드의 주요 쓰임 1) 레지스트리 같은 플랫폼 특화 기능 사용 자바가 성숙해가면서 (OS같은) 하부 플랫폼 기능을 흡수하고 있음 → 점차 네이티브 메서드 사용 필요성 감소 ex) 자바9는 processAPI를 추가하여 OS 프로세스에 접근할 수 있도록 함 2) 네이티브 코드로 작성된 기존 라이브러리 사용 레거시 데이터를 사용하는 레거시 라이브러리 대체할만한 자바 라이브러리가 없는 네이티브 라이브러리를 사용해야할때 네이티브 메서드 써야함 3) 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영..
리플렉션 ( java.io.reflect ) 리플렉션 기능을 이용하면 임의의 클래스에 접근할 수 있다. 자바 클래스파일 정보는 컴파일되면 클래스파일로 변환되어 메모리의 Static 영역에 위치 Static 영역의 정보는 언제든지 접근할 수 있기 때문에 클래스의 이름만 알면 정보들을 가져올 수 있음 Class 객체가 주어지면 그 클래스의 생성자, 메섣, 필드에 해당하는 인스턴스를 가져올 수 있음 인스턴스들로 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처 등을 가져올 수 있음 인스턴스를 이용하여 각각에 연결된 생성자, 메서드, 필드 조작 가능 (해당 클래스 인스턴스 생성, 메서드 호출, 필드 접근 등 가능) // 클래스 얻기 Class class = Class.forName(); //생성자 얻기 Co..
적합한 인터페이스만 있다면 매개변수[아이템 51] 뿐 아니라 반환값, 변수, 필드를 전부 클래스가 아닌 인터페이스 타입으로 선언하라. (객체의 실제 클래스를 사용할 상황은 오직 생성자로 생성할 때뿐) //좋은 예 : 인터페이스를 타입으로 사용 Set sonSet = new LinkedHashSet(); //나쁜 예 : 클래스를 타입으로 사용 LinkedHashSet sonSet = new LinkedHashSet(); 인터페이스를 타입으로 사용할 때 유연성 증가 프로그램이 훨씬 유연해진다. 나중에 구현 클래스를 교체하고 싶다면 그저 새 클래스의 생성자 or 다른 정적 팩터리를 호출해주기만 하면 된다. 다른 코드는 전혀 손대지 않아도 된다. //Set sonSet = new LinkedHashSet(); ..
문자열 연결 연산자 (+) 문자열 연결 연산자(+)는 여러 문자열을 편리하게 합쳐주지만, 본격적으로 사용하면 성능 저하를 감내하기 어려움 문자열 연결 연산자로 문자열 n개를 잇는 시간은 n^2에 비례 (문자열은 불변 [아이템 17] 이라서 두 문자열 연결 시 양쪽 내용을 모두 복사해줘야해서) //문자열 연결을 잘못 사용한 예 - 느리다 public String statement() { String result = ""; for(int i=0; i
문자열을 쓰지 않아야 할 사례 1) 문자열은 다른 값 타입을 대신하기에 적합하지 않다. 기본 타입이든 참조 타입이든 적절한 값 타입이 있다면 그것을 사용하고, 없다면 새로 하나 작성하라. 2) 문자열은 열거 타입을 대신하기에 적합하지 않다. 상수를 열거할때는 문자열보다 열거 타입이 월등히 좋다. [아이템 34] 3) 문자열은 혼합 타입을 대신하기에 적합하지 않다. 여러 요소가 혼합된 데이터를 하나의 문자열로 표현하는 것은 좋지 않다. String compoundKey = className + "#" + i.next(); 각 요소를 개별로 접근하려면 문자열을 파싱해야해서 느리고 귀찮고 오류 가능성도 커진다. equals, toString, compareTo 메서드를 제공할 수 없다. → 차라리 전용 클래스..
자바의 데이터 타입 기본 타입 : int, double, boolean 등 참조 타입 : String, List 각각의 기본타입에 대응하는 참조 타입이 하나씩 있음 → 박싱된 기본 타입 (Integer, Double, Boolean) 오토박싱과 오토언박싱 덕분에 두 타입을 크게 구분하지 않고 사용할 수 있지만, 둘 사이엔 분명한 차이가 있으니 뭘 사용하는진 매우 중요 기본 타입 vs 박싱된 기본 타입 1) 기본 타입은 값만 가지고 있지만, 박싱된 기본 타입은 값에 더해 식별성(identity)이란 속성도 갖고 있음 박싱된 기본 타입의 두 인스턴스는 값이 같아도 서로 다른 인스턴스라고 식별됨 ( == 로 비교시) Comprator naturalOrder = (i, j) -> (i < j) ? -1 : (i..
float와 double 연산은 정확하지 않다. (특히 금융 관련 계산과는 맞지 않음) double result = 1.03 - 0.42; System.out.println(result); // 0.6100000000000001 위와 같은 단순한 계산에도 오차가 발생한다. → float와 double은 부동소수점 방식을 사용하기 때문 부동소수점 방식 부동소수점 방식은 수를 정수와 실수로 구분하지 않고 지수부와 가수부로 구분한다. 소수점이 고정되지 않기 때문에 더 폭넓은 범위를 표현할 수 있지만, 필연적으로 오차가 발생하여 근사값을 구한다. 해결 방법 1) BigDecimal double 타입을 BigDecimal 을 사용하면 실수 연산을 오차없이 사용할 수 있다. BigDecimal은 기본 타입보다 쓰기..
static Random rnd = new Random(); static int random(int n){ return Math.abs(rnd.nextInt()) % n; } public static void main(String[] args) { int n = 2 * (Integer.MAX_VALUE / 3); int low = 0; for (int i = 0; i < 1_000_000; ++i) if (random(n) < n/2) low++; System.out.println(low); } 위 코드는 무작위 정수를 하나를 생성하는 코드인데 문제점이 많다. n이 그리 크지 않은 2의 제곱수라면 얼마 지나지 않아 같은 수열이 반복된다. n이 2의 제곱수가 아니라면 몇몇 숫자가 평균적으로 더 자주 반환된..