1. 웹은 HTTP로 나타낸다. 웹 브라우저에서 URL을 입력하고 웹 페이지가 보여지기까지 클라이언트의 요청과 서버의 응답이라는 과정을 거친다. 클라이언트에서 서버까지 일련의 흐름을 결정하고 있는 것은 웹에서 HTTP(HyperText Transfer Protocol)이라 불린다. 웹은 HTTP라는 약속을 사용한 통신으로 이루어져 있다. 2. 네트워크의 기본 TCP/IP HTTP를 이해하기 위해서는 TCP/IP의 개념을 알아야 한다. 인터넷을 포함해 우리가 일반적으로 사용하는 네트워크는 TCP/IP라는 프로토콜에서 움직이고 있다. TCP/IP는 인터넷에 관련된 다양한 프로토콜 집합의 총칭이며, HTTP도 그중 하나이다. 2.1 IP(Internet Protocol) 인터넷 쇼핑을 할 때 주소를 입력해야 ..
아무 메서드도 담고 있지 않고 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스를 마커 인터페이스라 한다. 대표적으로 Serializeable 인터페이스를 예로 들 수 있다. Serializeable은 자신을 구현한 클래스의 인스턴스는 직렬화할 수 있음을 알려주는 역할을 한다. 마커 애너테이션이 등장하면서 마커 인터페이스가 더 이상 쓸모없게 느껴질 수 있겠지만, 사실 마커 인터페이스는 두 가지 측면에서 마커 애너테이션보다 더 나은 점이 있다. 마커 애너테이션 VS 마커 인터페이스 마커 인터페이스가 가지는 강점 1. 마커 인터페이스는 이를 구현한 클래스의 인스턴스를 구분하는 타입으로 사용할 수 있다. 마커 애너테이션과는 다르게 마커 인터페이스는 타입이기 때문에 마커 애너테이션을 사용했..
@Override 애너테이션은 상위 타입의 메서드를 재정의했음을 나타낸다. 메서드 선언에만 달 수 있으며, 일관되게 사용하면 여러 가지 버그들을 예방할 수 있다. @Override는 의도를 명확히 나타낸다. @Override 애너테이션을 달아줌으로써 '재정의한다.'라는 의도를 명확히 나타낼 수 있다. 또한, 코드를 잘못 작성(Overriding이 아닌 Overloading)했을 경우 컴파일러가 잘못된 부분을 명확히 알려준다. @Override를 달지 않아도 되는 단 하나의 예외 구체 클래스에서 상위 클래스의 추상 메서드를 재정의할 때는 @Override를 달지 않아도 된다. 구체 클래스인데 아직 구현하지 않은 추상 메서드가 있다면 컴파일러가 이를 알려주기 때문이다. 하지만 @Override를 일괄적으로 ..
람다 표현식은 메서드로 전달할 수 있는 익명 함수를 단순화한 것이라고 할 수 있다. 즉, 컴파일러의 추론에 의지해서 코드를 단순화하는 것이다. 람다 표현식의 기본 구조는 다음과 같다. (i) -> i + 10; (인자 리스트) -> { 바디 }의 형태를 가진다. 위의 예제처럼 바디가 한 줄로 표현될 경우 { }와 return문을 생략할 수 있다. 하지만 여러 줄이라면 { }와 return문을 명시적으로 선언해줘야 한다. (x, y) -> { System.out.println("x + y"); return x + y; } 인자 리스트 1. 인자가 없을 경우 구현해야 하는 추상 메서드가 파라미터를 아무것도 받지 않는 경우에 사용한다. Supplier getSomeNumber = () -> 10; 2. 인자가..
명명 패턴이란 변수나 함수의 이름을 일관된 방식으로 작성하는 패턴을 말한다. 이러한 명명 패턴은 전통적으로 도구나 프레임워크에서 특별히 다뤄야 할 프로그램 요소에 구분을 위해 사용되어 왔다. 예를 들면 JUnit3 에서는 테스트 메서드 이름을 test로 시작하게끔 했다. 이러한 명명 패턴 방식은 효과적이지만 단점도 크다. 명명 패턴의 단점 1. 오타가 나면 안 된다. 만약 test로 시작되어야 할 메서드 이름이 오타로 인해 tset로 작성되었다면, 명명 패턴에는 벗어나지만 프로그램 상에서는 문제가 없기 때문에 테스트 메서드로 인식하지 못하고 테스트를 수행하지 않는다. 2. 명명 패턴을 의도한 곳에서만 사용할 거라는 보장이 없다. 개발자는 JUnit3의 명명 패턴인 'test'를 메서드가 아닌 클래스의 이..
열거 타입은 거의 모든 상황에서 타입 안전 열거 패턴(typesafe enum pattern)보다 우수하다. 단, 예외가 있다. 열거 타입은 확장을 할 수가 없다는 점이다. 즉, 타입 안전 열거 패턴은 확장을 통해 다음 값을 추가하고 다른 목적으로 사용할 수 있는 반면, 열거 타입은 그렇게 할 수없다. 하지만 대부분 상황에서 열거 타입을 확장하는 것은 좋지 않은 생각이다. 일반적으로 열거 타입 확장이 안 좋은 이유 확장한 타입의 원소는 기반 타입의 원소로 취급하지만 그 반대는 아니다. 기반 타입과 확장된 타입들의 원소 모두를 순회할 방법도 마땅치 않다. 확장성을 높이려면 고려할 요소가 늘어나 설계와 구현이 복잡해진다. 그렇다면 열거 타입 확장이 필요한 경우는 무엇일까? 확장할 수 있는 열거 타입은 연산 ..
배열이나 리스트에서 원소를 꺼낼 때 ordinal 메서드로 인덱스를 얻는 코드가 있다면 EnumMap을 활용해 해당 코드를 개선해야 한다. ordinal 메서드로 인덱스를 얻는 코드는 동작은 하지만 많은 문제점을 내포하고 있기 때문이다. ordinal 인덱싱의 문제점 식물의 생애주기를 열거 타입으로 표현한 다음 클래스를 예로 문제점을 살펴보자. class Plant{ enum LifeCycle { ANNUAL, PERENNIAL, BIENNIAL } final String name; final LifeCycle lifeCycle; public Plant(String name, LifeCycle lifeCycle) { this.name = name; this.lifeCycle = lifeCycle; } @..
열거 타입은 해당 상수가 몇 번째 위치에 존재하는지 반환하는 ordinal() 메서드를 제공한다. ordinal() 메서드는 Enum 클래스 내부에 존재하는 상수인 ordinal을 반환한다. Enum의 API 문서를 보면 ordinal에 대해 이렇게 쓰여 있다. "대부분의 프로그래머는 이 메서드를 쓸 일이 없다. 이는 EnumSet과 EnumMap 같이 열거 타입 기반의 범용 자료구조에 쓸 목적으로 설계되었다." 따라서 이런 용도가 아니라면 ordinal 메서드를 절대 사용해서는 안된다. ordinal 메서드를 사용하면 안 되는 이유 열거 타입 상수와 연결된 정수 값이 필요하면 orrdinal 메서드를 이용하고 싶을 수 있다. 예를 들어, 합주단의 종류를 연주자가 1명인 솔루부터 10명인 디텍트까지 정의..