Runnable과 Thread Java 1.0 버전에서는 Runnable과 Thread를 이용해 동시성 프로그래밍을 할 수 있었다. 이 방법은 직접 스레드를 생성하고 해당 스레드에서 원하는 동작을 수행하는 방법이다. Thread thread = new Thread(() -> System.out.println(Thread.currentThread().getName())); thread.start(); Thread-0 이 방법은 가장 간단하지만 스레드의 실행 결과로 나온 값을 메인 스레드에서 받기가 어렵다는 단점이 있다. 필요하다면 임시 array를 만들어서 리턴값을 넣어주는 방법이 있긴 하다. 그러나 다른 스레드에서 동작하기 때문에 값을 리턴했는지 알기 어렵다. 아래 코드처럼 join으로 스레드가 종료되기..
책
인터페이스의 제약 우리가 어떤 인터페이스에 새로운 기능을 추가하고 싶다고 하자. 우리가 만든 인터페이스를 나 혼자 사용한다면 문제없다. 인터페이스에 메소드를 추가하는 순간, IDE에서 수정이 필요한 곳을 모두 알려줄 것이기 때문에 조금 귀찮지만 감당할 수 있는 정도다. 그러나 회사 내부적으로 공유하고 있는 라이브러리의 인터페이스라면? 수 많은 개발자들이 라이브러리의 버전을 바꿨다가 수백개의 에러를 만나게 되고, 메소드를 하나하나 구현하느라 밤을 샐 수도 있다. 이렇게 컴파일 타임에 에러를 발견할 수 있으면 그나마 낫다. 만약 라이브러리 업데이트를 위해 운영중인 서버의 classpath에 있는 jar파일만 바꾸게 된다면 더 큰 문제다. 새롭게 추가된 메소드를 호출하기 전까지 문제를 알 수 없으며, 런타임에..
새로운 날짜, 시간 API의 필요성 Java 1.0 버전에는 날짜와 시간을 나타내기 위해 java.util 패키지의 Date라는 클래스가 있었다. 이 클래스는 여러 가지 문제가 많았다고 한다. 먼저, 클래스 이름부터 이상하다. 분명 이름이 Date인데 날짜뿐만 아니라 시간도 가지고있다. 또 연도는 1900년을 기준으로하며, 월은 0부터 시작해서 헷갈리는 방식을 채택했다. 예를 들어 2023년 3월 1일은 아래와 같이 만든다. Date date = new Date(123, 2, 1); 위 객체를 출력하면 꽤나 복잡한 문자열이 나온다. Wed Mar 01 00:00:00 KST 2023 알아볼 수는 있지만, 우리에게 익숙한 방식으로 바꾸고 싶다. 이 때 사용할 수 있는 클래스가 DateFormat인데, 이 ..
NullPointerException NullPointerException은 이름 그대로 pointer가 null인 경우에 발생하는데, Java에서는 pointer보다 reference라는 말이 더 어울릴지도 모르겠다. 이렇게 어떤 reference가 null일 때, 해당 reference를 통해 필드나 메소드 등에 접근하면 NullPointerException이 발생한다. 예를 들면 아래와 같은 경우다. Car car = null; car.drive(); 위의 두 줄의 코드가 NullPointerException의 모든 것이라고 보면 된다. 첫 번째로 reference가 null을 참조하고 있어야 하며, 두 번째로 그 reference를 통해 필드나 메소드에 접근하는 것이 바로 NullPointerEx..

스트림과 컬렉션 Java는 연속된 데이터를 처리하기 위해 List, Set같은 컬렉션 API를 지원한다. 그러나 컬렉션을 사용할 때, 사람들은 여전히 for문과 if 조건문, 그리고 여러 가지 변수들을 반복적으로 사용하게 된다. 또 다시 이전 예제를 가져오면 아래와 같은 코드가 전형적인 예시다. List coffee = new ArrayList(); for (Menu m : menu) { if (m.type == MenuType.COFFEE) { coffee.add(m); } } menu라는 컬렉션에 담겨있는 자료들을 탐색하면서 커피 종류의 메뉴만 보고싶다. 여기서 coffee라는 리스트를 만들기 위해 필요한 것은 menu라는 원래의 컬렉션과 m.type == MenuType.COFFEE라는 조건이면 충..
함수형 인터페이스 지난 글의 마지막에 사용자 정의 인터페이스를 대체할 수 있는 함수형 인터페이스를 언급했다. 이번 글에서는 함수형 인터페이스에 대해 자세히 알아보도록 하자. 먼저, 함수형 인터페이스라는 이름에 주목해보자. 인터페이스는 인터페이스인데, '함수형'이라니? 함수란 무엇인가? 고등학교 수학에서 자주 나오는 문제다. 정의역이 주어지고, 정의역에 속하는 x값은 모두 하나의 y값에 대응되어야 한다. y값이 0개도, 2개 이상도 안된다. (물론, y값은 공역의 원소여야한다.) 당연히 Java에서 x값은 파라미터에 해당하고, y값은 리턴값에 해당한다. 이것은 인터페이스로 정의한다면, 인터페이스 내에 구현이 없는 메소드 시그니처를 정의해주면 될 것이다. 근데 만약 메소드 시그니처가 2개라면 어떻게 될까? ..
동작 파라미터화 먼저 동작 파라미터화부터 알아보자. 말 그대로 어떤 동작을 파라미터로 전달한다는 뜻이다. 콜백 함수가 생각나기도 하고, 디자인 패턴의 템플릿 메소드 패턴, 전략 패턴, 데코레이터 패턴 등이 생각난다면 훌륭하다. 언제, 어떻게 실행될지 모르는 코드 조각을 다른 메소드에게 전달해주는 것이다. 예를 들면, 카페를 차린다고 해보자. public class Menu { String name; int price; MenuType type; public Menu(String name, int price, MenuType type) { this.name = name; this.price = price; this.type = type; } } MenuType으로는 커피, 케이크 두 가지만 있다고 하자. ..
프로그래밍 언어는 진화한다 Java 1.0은 1996년에 발표되어 거의 30년 가까이 지났다. 이 시간이 짧아보일 수 있지만, 그동안 PC와 인터넷이 보급되고, 스마트폰과 SNS, 글로벌 IT 기업들의 등장, AI의 발전 등의 사건이 일어났으니 컴퓨터과학의 역사와 함께했다고 해도 과언이 아니다. 프로그래밍 언어들은 계속해서 새로 생겨난다. Go, Rust, Kotlin 등은 비교적 최근에 나타나 꽤 많은 곳에서 사용되고 있다. 반면 Pascal, ALGOL, Ada 같은 언어들로 새로운 프로젝트를 만드는 곳은 없을 것이다. 이렇게 프로젝트의 요구사항에 따라 적절한 언어를 선택하고, 선택받지 못한 언어들은 잊혀져간다. 진화론의 자연선택과 비슷하다. Java 8 Java도 마찬가지로 새로운 요구사항을 반영하..