리플렉션 기능(java.lang.reflect)을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있습니다. Class 객체가 주어지면 그 클래스의 생성자, 메서드, 필드에 해당하는 Constructor, Method, Field 인스턴스를 가져올 수 있고, 이어서 이 인스턴스들로는 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처 등을 가져올 수 있습니다. 나아가 Constructor, Method, Field 인스턴스를 이용해 각각에 연결된 실제 생성자, 메서드, 필드를 조작할 수도 있습니다. 이 인스턴스들을 통해 해당 클래스의 인스턴스를 생성하거나, 메서드를 호출하거나, 필드에 접근할 수 있다는 뜻입니다. 예를 들어 Method.invoke는 어떤 클래스의 어떤 객체가 가진 어떤 메서드라도 호출..
아이템 51에서 매개변수 타입으로 클래스가 아니라 인터페이스를 사용하라고 했습니다. 이 조언을 "객체는 클래스가 아닌 인터페이스로 참조하라"고까지 확장할 수 있습니다. 적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라. 객체의 실제 클래스를 사용해야 할 상황은 '오직' 생성자로 생성할 때뿐입니다. 예를 들어 다음은 Set 인터페이스를 구현한 LinkedHashSet 변수를 선언하는 올바른 모습입니다. // 좋은 예. 인터페이스를 타입으로 사용했다. Set sonSet = new LinkedHashSet(); // 나쁜 예. 클래스를 타입으로 사용했다. LinkedHashSet sonSet = new LinkedHashSet(); 인터페이스를 타입으로 사..
문자열 연결 연산자(+)는 여러 문자열을 하나로 합쳐주는 편리한 수단입니다. 그런데 한 줄짜리 출력값 혹은 작고 크기가 고정된 객체의 문자열 표현을 만들때라면 괜찮지만, 본격적으로 사용하기 시작하면 성능 저하를 감내하기 어렵습니다. 문자열 연결 연산자로 문자열 n개를 잇는 시간은 n의 2승에 비례합니다. 문자열은 불변(아이템 17)이라서 두 문자열을 연결할 경우 양쪽의 내용을 모두 복사해야 하므로 성능 저하는 피할 수 없는 결과로 작용합니다. 예를 들어 다음 메서드는 청구서의 품목(item)을 전부 하나의 문자열로 연결해줍니다. public String statement() { String result = ""; for( int i = 0; i< numItems(); i++) result += lineF..
문자열(String)은 텍스트를 표현하도록 설계되었고, 그 일을 아주 멋지게 해냅니다. 그런데 문자열은 워낙 흔하고 자바가 또 잘 지원해주어 원래 의도하지 않은 용도로도 쓰이는 경향이 있습니다. 이번 아이템에서는 문자열을 쓰지 않아야 할 사례를 다룹니다. 문자열은 다른 값 타입을 대신하기에 적합하지 않습니다. 많은 사람이 파일, 네트워크, 키보드 입력으로부터 데이터를 받을 때 주로 문자열을 사용합니다. 사뭇 자연스러워 보이지만, 입력받을 데이터가 진짜 문자열일 때만 그렇게 하는 게 좋습니다. 받은 데이터가 수치형이라면, int, float, BigInteger 등 적당한 수치 타입으로 변환해야 합니다. '예/아니오' 질문의 답이라면 적절한 열거 타입이나 boolean으로 변환해야 합니다. 일반화해 이야기..
자바의 데이터 타입은 크게 두 가지로 나눌 수 있습니다. 바로 int, double, boolean 같은 기본 타입과 String, List와 같은 참조 타입입니다. 그리고 각각의 기본 타입에는 대응하는 참조 타입이 하나씩 있으며, 이를 박싱된 기본 타입이라고 합니다. 예컨대 int, double, boolean에 대응하는 박싱된 기본 타입은 Integer, Double, Boolean 입니다. 아이템 6에서 이야기했듯, 오토박싱과 오토언박싱 덕분에 두 타입을 크게 구분하지 않고 사용할 수는 있지만, 그렇다고 차이가 사라지는 것은 아닙니다. 둘 사이에는 분명한 차이가 있으니 어떤 타입을 사용하는지는 상당히 중요합니다. 즉, 주의해서 선택해야 한다는 의미입니다. 기본 타입과 박싱된 기본 타입의 주된 차이는..
float와 double 타입은 과학과 공학 계산용으로 설계되었습니다. 이진 부동소수점 연산에 쓰이며, 넓은 범위의 수를 빠르게 정밀한 '근사치'로 계산하도록 설계되었습니다. 따라서 정확한 결과가 필요할 때는 사용하면 안 됩니다. float와 double 타입은 특히 금융 관련 계산과는 맞지 않습니다. 0.1 혹은 10의 음의 거듭제곱 수를 표현할 수 없기 때문입니다. 예를 들어 주머니에 1.03달러가 있었는데 그 중 42센트를 썼다고 해봅시다. 🤔 남은 돈은 얼마인가요? 다음은 이 문제의 답을 구하기 위해 작성된 코드입니다. System.out.println(1.03 - 0.42); 안타깝게도 이 코드는 0.6100000001을 출력합니다. 결괏값을 출력하기 전에 반올림하면 해결되리라 생각할지 모르지만..
무작위 정수 하나를 생성하고 싶다고 해봅시다. 값의 범위는 0부터 명시한 수 사이입니다. 아주 흔히 마주치는 문제로, 많은 프로그래머가 다음과 같은 짤막한 메서드를 만들곤 합니다. static Random rnd = new Random(); static int random(int n) { return Math.abs(rnd.nextInt()) % n; } 괜찮은 듯 보여도 문제를 세 가지나 내포하고 있습니다. 위 코드의 문제점 [1]. n이 그리 크지 않은 2의 제곱수라면 얼마 지나지 않아 같은 수열이 반복된다. [2]. n이 2의 제곱수가 아니라면 몇몇 숫자가 평균적으로 더 자주 반환된다. n 값이 크면 이 현상은 더 두드러집니다. 다음 코드는 무작위 수를 백만개를 생성한 다음, 그 중 중간 값보다 작..
아이템 45에서 이야기했듯, 스트림이 제격인 작업이 있고 반복이 제격인 작업이 있습니다. 다음은 전통적인 for 문으로 컬렉션을 순회하는 코드입니다. for (Iterator i = c.iterator(); i.hasNext(); ) { Element e = i.next(); } 그리고 다음은 전통적인 for 문으로 배열을 순회하는 코드입니다. for (int i = 0; i < a.length; i++) { ... // a[i]로 무언가를 한다. } 이 관용구들은 while 문보다는 낫지만(아이템 57) 가장 좋은 방법은 아닙니다. 반복자와 인덱스 변수는 모두 코드를 지저분하게 할 뿐 우리에게 진짜 필요한 건 원소들뿐입니다. 더군다나 이처럼 쓰이는 요소 종류가 늘어나면 오류가 생길 가능성이 높아집니다...
- Total
- Today
- Yesterday
- programmers
- Java
- 클린 코드
- kkoon9
- 테라폼
- kotest
- 객체지향
- 알고리즘
- 백준
- 이펙티브 자바
- MSA
- BAEKJOON
- 프로그래머스
- 디자인 패턴
- JPA
- Algorithm
- Effective Java
- 클린 아키텍처
- 코테
- Olympiad
- Spring
- 디자인패턴
- Spring Boot
- node.js
- Kotlin
- 이팩티브 자바
- 정규표현식
- AWS
- C++
- BOJ
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |