자바 플랫폼은 명명 규칙이 잘 정립되어 있으며, 대부분 자바 언어 명세(JLS)에 기술되어 있다. 자바의 명명 규칙은 크게 철자와 문법 두 범주로 나뉜다. 1. 자바의 명명 규칙 - 철자 철자 규칙은 패키지, 클래스, 인터페이스, 메서드, 필드, 타입 변수의 이름 등을 다룬다. 이 규칙을 어긴 API는 사용하기 어려우며 유지 보수하기도 어렵다. 또한, 코드를 읽기 번거로워지고 다른 뜻으로도 오해할 수 있으므로 반드시 따르는 것이 좋다. 패키지, 모듈 (.)으로 구분하여 계층적으로 짓는다. 소문자 알파벳으로 구성되며, 드물게 숫자가 들어가기도 한다. 바깥에서도 사용하는 패키지라면 도메인의 역순으로 구성한다. 각 요소는 8자 이하의 짧은 단어를 사용한다. util 처럼 의미가 통하는 약어를 사용하는 것도 좋..
섣불리 최적화를 진행하면 좋은 결과보다 해로운 결과로 이어지기 쉽다. 빠르지도 않고 제대로 동작하지 않으면서 수정하기 어려운 소프트웨어가 될 수 있는 것이다. 우리는 빠른 프로그램보다 좋은 프로그램을 만들어야 한다. 좋은 프로그램은 개별 구성요소의 내부를 독립적으로 설계할 수 있다. 따라서 시스템의 나머지에 영향을 주지 않고도 각 요소를 다시 설계할 수 있다. 좋은 프로그램을 만들었지만 성능이 나오지 않는다면 그 아키텍처가 최적화할 수 있는 길을 안내해줄 것이다. 설계 단계에서 성능을 고려하자 프로그램의 구현상의 성능 이슈는 나중에 최적화로 해결할 수 있지만, 아키텍처의 결함이 성능을 해치는 상황이라면 시스템 전체를 다시 만들지 않고서는 해결 불가능할 수도 있다. 완성된 설계의 기본 틀을 변경하려다 보면..
자바 네이티브 인터페이스는 자바 프로그램이 C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드를 호출하는 기술이다. 이러한 네이티브 메서드를 사용하려면 한번 더 생각하고 신중히 사용해야 한다. 네이티브 메서드가 주로 사용된 경우 1. 윈도우 레지스트리 같은 플랫폼 특화 기능을 사용한다. 2. 네이티브 코드로 작성된 기존 라이브러리를 사용한다. 3. 성능 개선을 목적으로 성능에 결정적 영향을 주는 부분만 따로 네이티브 언어로 작성한다. 네이티브 메서드를 권장하지 않는 이유 1. 자바가 성숙해지면서 플랫폼의 기능들을 흡수하고 있다. 플랫폼 특화 기능을 사용하려면 네이티브 메서드가 필요하다. 하지만 자바 언어가 발전해가면서 OS와 같은 하부 플랫폼의 기능들을 점차 흡수하고 있다. 따라서 네이티브 메서드를..
리플렉션 기능 리플렉션 기능을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다. Class 객체가 주어지면 그 클래스의 생성자, 메서드, 필드 인스턴스를 가져올 수 있고, 해당 인스턴스들로부터 클래스의 멤버 이름, 필드 타입, 메서드 시그니처 등을 가져올 수 있다. 나아가 각 인스턴스를 이용해 연결된 실제 생성자, 메서드, 필드를 조작할 수 있다. 이는 클래스의 인스턴스를 생성하거나, 메서드를 호출하고, 필드에 접근할 수 있음을 나타낸다. 리플렉션을 이용하면 컴파일 당시에 존재하지 않던 클래스도 이용할 수 있다. 리플렉션의 단점 1. 컴파일 타임 타입 검사가 주는 이점을 누릴 수 없다. 타입 검사나 예외 검사의 이점을 누릴 수 없다. 리플렉션 기능을 이용해 존재하지 않거나 접근할 수 없는 메서드를 ..
적합한 인터페이스만 있다면 매개변수뿐 아니라 반환 값, 변수, 필드를 전부 인터페이스 타입으로 선언하자. 실제 클래스를 사용해야 하는 상황은 생성할 때뿐이다. 인터페이스를 타입으로 선언하는 습관은 프로그램을 훨씬 유연하게 만들어 준다. 인터페이스를 타입으로 선언하자. // Good Set sonSet = new LinkedHashSet(); // Bad LinkedHashSet sonSet = new LinkedHashSet(); 위 예시에서 구현 클래스를 교체하고자 한다면 아래와 같이 변경할 수 있다. Set sonSet = new HashSet(); 이처럼 인터페이스를 타입으로 사용한 선언은 간단하게 새로운 구현 클래스로 교체할 수 있다. 주의사항 만약 인터페이스의 일반 규약 이외의 특별한 기능에 의..
문자열 연결 연산자(+)는 여러 문자열을 하나로 합쳐주는 편리한 수단이지만, 성능 저하가 상당하다. 문자열 연결 연산자로 문자열 n개를 잇는 작업은 n^2에 비례한다. 예시 청구서의 item을 전부 하나의 문자열로 연결하는 메서드가 있다. // 문자열 연결을 잘못 사용한 예 - 느리다! public String statement() { String result = ""; for (int i = 0; i < numItems(); i++) { result += lineForItem(i); } return result; } 각 item의 원소 개수만큼 문자열을 잇는다. 품목의 개수가 많아지면 많아질수록 성능 저하가 심해진다. 성능을 포기하고 싶지 않다면 String 대신 StringBuilder를 사용하자! ..
문자열은 텍스트를 표현하도록 설계되었다. 하지만 워낙 흔하고 자바가 잘 지원해주기 때문에 설계 의도와 다르게 사용될 때가 많다. 문자열을 쓰지 않아야 할 사례들 1. 문자열로 다른 값 타입을 대신하는 경우 받는 데이터가 수치를 나타낸다면 int, float, BigInteger 등을, Y / N을 나타낸다면 boolean을 사용하는 것이 적절하다. 즉, 기본 타입이든 참조 타입이든 알맞는 값 타입이 있다면 그것을 사용하고, 없다면 새로 만들어서 사용하자. 2. 문자열로 열거 타입을 대신하는 경우 아이템 34에서도 설명했듯, 상수를 열거할 때는 문자열보다 열거 타입을 사용하자. 3. 문자열로 혼합 타입을 표현하는 경우 혼합된 데이터를 하나의 문자열로 표현하는 것은 좋지 않은 생각이다. // 혼합 타입을 문..
자바의 데이터 타입은 크게 int, long, boolean과 같은 기본 타입과 String, List 같은 레퍼런스 타입으로 나눌 수 있다. 각각의 기본 타입에는 대응하는 레퍼런스 타입이 하나씩 존재하고, 이를 박싱 된 기본 타입(Integer, Long, Boolean 등)이라 한다. 오토 박싱과 오토 언박싱 덕분에 두 타입을 크게 구분하지 않고 사용할 수 있지만, 어떤 타입을 선택하고 사용하는지는 상당히 중요하다. 이 둘의 차이점을 명확히 파악하고 사용해야 발생하는 문제들을 최소화할 수 있다. 기본 타입과 박싱된 기본 타입의 차이점 1. 기본 타입은 값만 가지고 있으나, 박싱 된 기본 타입은 식별성도 가지고 있다. 박싱 된 기본 타입의 두 인스턴스는 값이 같아도 서로 다른 인스턴스로 인식될 수 있다..
float와 double 타입은 공학 계산용으로 설계되었다. 넓은 범위의 수를 빠르게, 정밀한 근사치로 계산하도록 설계되었다. 따라서 정확한 결과가 필요할 때는 사용하면 안 된다. 특히, 금융(돈) 관련 계산에는 float와 double 타입 사용을 피하자. 금융 계산에 부동소수 타입을 사용한 경우 public static void main(String[] args) { double funds = 1.00; int itemBought = 0; for(double price = 0.10; funds >= price; price += 0.10) { funds -= price; itemsBought++; } System.out.println(itemBought + "개 구입"); System.out.print..