맞는데 왜 틀릴까..?

분류 전체보기 306

[Effective Java] Item 70. 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라

자바는 문제 상황을 알리는 타입(throwable)으로 검사 예외, 런타임 예외, 에러를 제공한다. 언제 무엇을 사용할지 헷갈리는 프로그래머들이 많기 때문에 참조할 좋은 지침들이 있다. 1. 검사 예외 (Checked Exception) Exception 클래스를 상속받은 예외 타입 중에서 RuntimeException을 제외한 나머지 예외들 컴파일러가 검사 예외를 체크하고, 예외를 처리하지 않으면 컴파일 오류가 발생한다. I/O 문제, 네트워크 연결 실패 등 프로그램의 외부적인 환경 변화에 따른 문제 상황을 나타내는 데 사용된다. 2. 런타임 예외 (Runtime Exception) RuntimeException 클래스를 상속받은 예외 타입을 가리킨다. 컴파일러가 이 예외를 체크하지 않으며, 예외 처리..

Java/Effective Java 2023.08.05

[Effective Java] Item 69. 예외는 진짜 예외 상황에만 사용하라

예외는 오직 예외 상황에서만 써야 한다. 절대로 일상적인 제어 흐름용으로 쓰여선 안된다. 부적절한 예 - 예외를 사용한 최적화 배열의 원소를 순회하는 표준적인 관용구 for (Mountain m : range) m.climb(); 완전히 잘못 사용한 예외를 활용한 최적화 try{ int i =0; while(true) range[i++].climb(); } catch (ArrayIndexOutOfBoundsException e){ } 최적화를 위한 잘못된 추론 JVM은 배열에 접근할 때마다 경계를 넘지 않는지 검사한다. 일반적인 반복문도 배열 경계에 도달하면 종료한다. 따라서 경계를 넘는지 검사하는 일이 중복되므로 생략해 버리자. 추론이 잘못된 점 예외는 예외 상황에 쓸 용도로 설계되었으므로 명확한 검사..

Java/Effective Java 2023.08.05

[Effective Java] Item 68. 일반적으로 통용되는 명명 규칙을 따르라

자바의 명명 규칙은 크게 철자와 문법 두 범주로 나뉜다. 철자 규칙 : 패키지, 클래스, 인터페이스, 메서드, 필드, 타입 변수 철자 규칙이나 문법 규칙을 어기면 다른 프로그래머들이 그 코드를 읽기 번거로울 뿐 아니라 다른 뜻으로 오해할 수도 있다. 철자 규칙 철자 규칙은 특별한 이유가 없는 한 반드시 따라야 한다. 이 규칙을 어긴 API는 사용하기 어렵고, 유지보수하기 어렵다. 패키지 패키지와 모듈 이름은 각 요소를 점(.)으로 구분하여 계층적으로 짓는다. 요소들은 모두 소문자 알파벳 혹은 드물게 숫자로 이루어진다. 각 요소는 일반적으로 8 자 이하의 짧은 단어로, 그 단어의 약어 또는 첫 글자만 따서 지어도 좋다. 인터넷 도메인 이름을 역순으로 사용한다. 예외적으로 표준 라이브러리와 선택적 패키지들은..

Java/Effective Java 2023.08.04

[Secure Coding] 민감한 가변적 클래스에 수정이 불가능한 래퍼를 제공하라

필드의 불변성(immutability)은 악의적인 변경뿐만 아니라 부주의로 인한 변경도 방지하여, 입력을 받아들이거나 값을 반환할 때 방어적인 복사가 불필요해진다. 그러나 일부 민감 클래스들은 불변성을 가질 수 없다. 만약 필드가 가변 객체라면 객체의 무결성을 위해 방어적 복사를 수행해야 한다. 부적절한 코드 - 내부 배열 객체의 수정을 허용 getter와 setter로 객체 내부 불변성 위협 비신뢰-호출자(untrusted invoker)는 setter를 호출하여 객체의 불변성을 위반 접근자 getter를 호출하여 Mutable의 내부 상태 수정 가능 가변적 private 클래스 멤버에 대한 레퍼런스를 반환하기 전에 멤버들을 복사하여 방어해야 한다. 솔루션 - 방어적 복사와 예외 발생 접근자 gette..

Java/Secure Coding 2023.08.04

[Effective Java] Item 67. 최적화는 신중히 하라

이 책에서 모든 사람이 마음 깊이 새겨야 할 최적화 격언 3개를 소개해주었다. 그 어떤 핑계보다 효율성이라는 이름 아래 행해진 컴퓨팅 죄악이 더 많다 - 윌리엄 울프 전체의 97% 정도인 자그마한 효율성은 모두 잊자. 섣부른 최적화가 만악의 근원이다. - 도널드 크누스 최적화를 할 때는 다음 두 규칙을 따르라. 1. 하지 마라 2. (전문가 한정) 아직 하지 마라. 다시 말해, 완전히 명백하고 최적화되지 않은 해법을 찾을 때까지는 하지 마라 - M.A. 잭슨 이 격언들은 자바가 탄생하기 20년 전에 나온 것으로, 최적화는 좋은 결과보다는 해로운 결과로 이어지기 쉽고, 섣불리 진행하면 특히 더 그렇다는 것을 알려준다. 성능 때문에 견고한 구조를 희생하지 말자. 빠른 프로그램보다는 좋은 프로그램을 작성하자...

Java/Effective Java 2023.08.03

[Secure Coding] 클라이언트에 암호화되지 않은 민감-데이터를 저장하지 말라

클라이언트-서버 모델을 사용하는 응용프로그램을 작성할 때, 사용자 인증 정보와 같은 민감-데이터를 클라이언트 측에 저장하면, 클라이언트가 공격에 취약할 경우에 허가되지 않은 방법으로 민감-데이터가 노출될 수 있다. 민감-데이터 사용자 이름, 패스워드, 신용 카드 번호 등 사용자 개인을 식별할 수 있는 기타의 정보 쿠키(cookie) 웹 응용프로그램에서 이 문제에 대한 가장 보편적인 완화책 짧은 문자열로 구성되어 있고, 만약 민감-데이터를 포함하고 있다면(remember-me 기능) 암호화되어야만 한다. 쿠키를 클라이언트에게 제공하고 민감-데이터는 서버에 저장 쿠키는 웹서버에 의해 생성되고 일정 기간 동안 클라이언트에 저장됨. 클라이언트가 서버에 다시 연결할 때, 클라이언트가 서버에게 자신을 식별하도록 하..

Java/Secure Coding 2023.08.03

[Effective Java] Item 66. 네이티브 메서드는 신중히 사용하라

네이티브 메서드 C, C++ 같은 네이티브 프로그래밍 언어로 작성한 메서드다. 자바 네이티브 인터페이스는 자바 프로그램이 네이티브 메서드를 호출하는 기술이다. 네이티브 메서드의 주요 쓰임 1. 레지스트리 같은 플랫폼 특화 기능을 사용한다. 2. 네이티브 코드로 작성된 기존 라이브러리를 사용한다. ex) 레거시 테이터를 사용하는 레거시 라이브러리 ( 더 이상 쓰기 힘들고 정상적이지 않는 화나게 만드는 난해한 코드) 3. 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 작성한다. 성능을 개선할 목적으로 네이티브 메서드를 사용하는 것은 권장하지 않는다. 자바 초기 시절이라면 이야기가 다르지만, JVM은 그동안 엄청난 속도로 발전해 왔기 때문에 대부분에 작업에서 지금의 자바는 다른..

Java/Effective Java 2023.07.30

[Effective Java] Item 65. 리플렉션보다는 인터페이스를 사용하라

리플렉션(Reflection) 프로그램 실행 중에 클래스의 정보를 동적으로 가져오고, 해당 클래스의 인스턴스를 생성하거나 메서드를 호출하는 기능을 말한다. 즉, 리플렉션을 통해 실행 중인 자바 프로그램이 자신의 구조를 분석하고 수정할 수 있는 능력을 갖게 된다. 1. 리플렉션 기능을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다. Class 객체가 주어지면 그 클래스의 생성자, 메서드, 필드에 해당하는 Constructor, Method, Field 인스턴스를 가져올 수 있고, 이어서 이 인스턴스들로는 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처들을 가져올 수 있다. Constructor, Method, Field 인스턴스를 이용해 각각에 연결된 실제 클래스의 인스턴스를 생성하거나, 메서..

Java/Effective Java 2023.07.30

[Effective Java] Item 64. 객체는 인터페이스를 사용해 참조하라

객체의 실제 클래스를 사용해야 할 상황은 오직 생성자로 생성할 때뿐이다. 적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라. Set 인터페이스를 구현한 LinkedHashSet 변수를 선언 // 좋은 예 : 인터페이스를 타입으로 사용했다. Set sonSet = new LinkedHashSet(); // 나쁜 예 : 클래스를 타입으로 사용했다. LinkedHashSet sonSet = new LinkedHashSet(); 인터페이스를 타입으로 사용하는 습관을 길러두면 프로그램이 훨씬 유연해진다. 나중에 구현 클래스를 교체하고자 한다면 그저 새 클래스의 생성자를 호출해주기만 하면 된다. 다른 코드는 전혀 손대지 않고 새로 구현한 클래스로의 교체를 완료할 ..

Java/Effective Java 2023.07.30

[Effective Java] Item 63. 문자열 연결은 느리니 주의하라

문자열 연결 연산자(+) 문자열 연결 연산자(+)는 여러 문자열을 하나로 합쳐주는 편리한 수단이다. 한 줄짜리 출력값 혹은 작고 크기가 고정된 객체의 문자열 표현을 만들 때라면 괜찮지만, 본격적으로 사용하기 시작하면 성능 저하를 감내하기 어렵다. 문자열 연결 연산자로 문자열 n개를 잇는 시간은 n^2에 비례한다. 문자열은 불변이라서 두 문자열을 연결할 경우 양쪽의 내용을 모두 복사해야 한다. StringBuilder를 사용하자. 결론 성능에 신경 써야 한다면 많은 문자열을 연결할 때는 문자열 연결 연산자(+)를 피하자. 대신 StringBuilder의 append 메서드를 사용하자.

Java/Effective Java 2023.07.30