전체 글

여러분 안냐세욤
필드를 노출하면 캡슐화가 깨진다 public 클래스에는 절대 가변 필드를 직접 노출해서는 안된다. (불변 필드도 안심할 수 없다.) 하지만 package-private 클래스나 private 중첩 클래스에서는 종종 필드를 필드를 노출하는 편이 나을 때도 있다. 일단 public 클래스에서 데이터 필드에 직접 접근한다면 캡슐화가 깨지는 것이다(Item15). 그렇게 되면 단점이 많은데, 불변식을 보장할 수도 없고, 외부에서 필드에 접근할 때 부수 작업을 수행할 수도 없다. 그래서 필드는 모두 private으로 바꾸고, 접근자(getter) 및 변경자(mutator, setter)를 두는 방식으로 개선할 수 있다. 노출해도 되는 상황이 있나요? 하지만 pakage-private 클래스 혹은 private 중..
캡슐화 잘 설계된 컴포넌트의 기본은 내부 정보를 외부로부터 잘 은닉하기! 즉 캡슐화이다. 내부 구현을 완벽히 숨겨서 "구현"과 "API"를 깔끔히 분리하는 것이다. 소프트웨어 설계의 근간이다! 항상 고민하도록 하자. 캡슐화 장점은 간단히.. - 시스템 개발 속도를 높인다. - 시스템 관리 비용을 낮춘다. - 캡슐화 자체가 성능을 높여주진 않으나 최적화에 도움을 준다. (다른 컴포넌트에 영향 주지 않고 해당 컴포넌트만 최적화 가능) - 재사용성을 높인다. - 큰 시스템 제작 난이도를 낮춘다. 접근 제한자를 잘 다루는 것이 중요 private, protected, public ... 을 잘 활용하는 것이 캡슐화의 핵심이다! 기본 원칙은 간단하다. "모든 클래스와 멤버의 접근성을 가능한 좁혀야 한다"는 것이다..
최적화의 어두운 진실 최적화는 해로운 결과로 이어지기 쉽다. 빠르지도, 제대로 동작하지도 않고, 수정하기도 어려운 소프트웨어를 탄생시킬 수 있다. 성능 때문에 견고한 구조를 희생하지 말자. 빠른 프로그램보다는 좋은 프로그램을 작성하라. 좋은 프로그램은 정보 은닉 원칙을 따르므로, 구성요소의 각 내부를 독립적으로 재설계 가능하다(Item15) . . 책에서는 "모든 사람이 마음 깊이 새겨야 할 최적화 격언 세 개"를 소개하고 있다. 이 격언들은 자바가 탄생하기 20년 전에 나온 것으로, 최적화의 어두운 진실을 이야기해준다. (맹목적인 어리석음을 포함해) 그 어떤 핑계보다 효율성이라는 이름 아래 행해진 컴퓨터 죄악이 더 많다(심지어 효율을 높이지도 못하면서). ─ 윌리엄 울프 (전체의 97% 정도인) 자그마..
네이티브 메서드 네이티브 메서드란, C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드를 말한다. 자바 네이티브 인터페이스(JNI)는 자바 프로그램이 그런 네이티브 메서드를 호출하는 기술이다. 네이티브 메서드의 주요 쓰임 1. 레지스트리 같은 플랫폼 특화 기능을 사용할 때 └ 필요성 줄어드는 중임: 자바가 성숙해가면서 하부 플랫폼(OS 등)의 기능들을 점차 흡수중 2. 네이티브 라이브러리(네이티브 코드로 작성된)를 사용할 때 └ 네이티브 라이브러리는 특히 GNU 다중 정밀 연산 라이브러리(GMP)를 필두로 개선 작업 계속되어옴 └ 고성능 다중 정밀 연산이 필요하다면, 네이티브 메서드를 통해 GMP를 사용하는 것을 고려해도 좋음 3. 성능 개선을 목적으로 사용함 └ 비권장: 요즘 자바는 다른 플랫폼에..
리플렉션 리플렉션 기능(java.lang.reflect)을 이용하면 임의의 클래스에 접근할 수 있다. 예를 들어 Class 객체가 주어지면 그 클래스의 Constructor, Method, Field 인스턴스를 가져올 수 있고, 이어서 이 인스턴스들로는 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처 등을 가져올 수 있다. 더 나아가서 Constructor, Method, Field 인스턴스를 이용해 각각에 연결된 실제 생성자, 메서드, 필드를 조작할 수도 있다. (저 인스턴스들을 통해 해당 클래스의 인스턴스를 생성하거나, 메서드를 호출하거나, 필드에 접근할 수 있음) 예를 들어 Method.invoke를 통해 어떤 객체의 메서드를 호출할 수 있다. 이렇게 리플렉션을 이용하면 컴파일 시점에 존재하지..
클래스를 타입으로 사용하지 마라 매개변수 타입을 지정할 때, 클래스가 아닌 인터페이스를 사용하라고 했다. (Item51) 이 조언을 확장한다면 "객체는 클래스가 아닌 인터페이스로 참조하라"는 의미이다. 유연한 프로그래밍을 위하여.. 매개변수 뿐 아니라, 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라. 객체의 실제 클래스를 사용해야 할 상황은 '오직' 생성자로 생성할 때뿐이다. 클래스를 타입으로 사용하지 말아라! // O Set sonSet = new LinkedHashSet(); // X LinkedHashSet sonSet = new LinkedHashSet(); 주의점 구현 클래스를 갈아끼우는 상황을 떠올려보자. 기존의 클래스가 인터페이스의 일반 규약 이외의 특별한 기능을 제공하는 상태고,..
문자열 연결 연산자(+)를 피하라 문자열 연결 연산자(+)로 문자열 n개를 잇는 시간은 n^2에 비례한다 문자연은 불변(Item17)이라서 두 문자열을 연결할 경우 양쪽 문자열 내용을 모두 복사해야 하므로 성능 저하가 있다. public String statement() { String result = ""; for (int i=0; i
문자열로 다른 타입을 대체하지 마라 : 문자열을 쓰고 싶은 유혹을 뿌리쳐라 "입력받을 데이터가 진짜 문자열일 때만 그렇게 하는 것이 좋다" 받은 데이터가 수치형이면 int, float, BigInteger 등으로 해야 하고, 예/아니오 형태라면 enum이나 boolean으로 해야 한다. 적절한 데이터 타입이 있다면 그것을 사용해야 한다. 없다면 데이터 타입을 새로 작성하는 편이 좋다. 지켜지지 않는 경우가 많아서 하는 이야기이다 (← 헉 저도 안 지키고 있었어요..!) 혼합 타입을 문자열로 표현하지 마라 className과 i.next()의 혼합 정보를 "#"로 구분하여 문자열 데이터로 보관하고 있다. 두 요소를 구분해 주는 문자 "#"가 명확하므로 괜찮지 않을까? // 부적절 예시 String comp..
기본타입과 박싱된 타입 기본 타입 int, double, boolean 등은 각각 대응하는 참조 타입이 하나씩 있다. 박싱된 기본 타입 즉 Integer, Double, Boolean이다. 오토박싱과 오토언박싱 덕분에 두 타입을 크게 구분할 필요는 없지만, 차이점은 존재하며 주의해서 선택해야 한다. 차이점은 크게 세가지다. 1. 기본 타입은 값만 가지고 있으나, 박싱된 타입은 값에 더해 식별성(identity) 속성을 갖는다. └ 즉 박싱된 타입인 두 인스턴스는 값이 같아도 서로 다른 객체다. 2. 기본 타입의 값은 언제나 유효하지만, 박싱된 타입은 유효하지 않은 값 null을 가질 수 있다. 3. 기본 타입이 박싱된 타입보다 시간과 메모리 사용면에서 효율적이다. 이렇게 기본 타입을 박싱하는 작업은, 필..
float, double이 근사치임을 유의하기! 정확한 결과가 필요할 때는 float, double을 사용하면 안 된다. 정밀한 근사치로 계산하도록 설계되었기 때문이다. 특히 금융 계산과는 맞지 않는데, 10의 음의 거듭제곱 수를 표현할 수 없기 때문이다. 다음은 와닿는 예시이다. → 1.03달러 - 42센트는? System.out.println(1.03 - 0.42); 를 해보면 0.610000000000001을 출력한다. → 1달러가 있었는데 10센트 사탕 9개를 사면? System.out.println(1.00 - 9 * 0.10); 은 0.999999999999998을 출력한다. BigDecimal, int, long을 사용! 정확한 결과가 필요한 금융 계산에서는 BigDecimal, int, l..
히어로맛쿠키
자꾸 생각나는 체리쥬빌레