자바가 제공하는 다중 구현 매커니즘에는 추상 클래스와 인터페이스가 있다. 아주 친숙한 개념이지만 막상 다중 구현을 할 때 어떤 매커니즘을 사용해야 할지 의문이 생길 때가 많다. Java8부터는 인터페이스가 디폴트 메서드를 제공하게 되면서 추상 클래스와 인터페이스 간의 차이가 더 줄어들었다. 이 말은, 추상 클래스가 할 수 있는 일은 인터페이스도 할 수 있게 되었다는 뜻이다. 그렇다면 대체 언제 추상 클래스를 사용하고 언제 인터페이스를 사용해야 하는 것일까? 추상 클래스 추상 클래스의 핵심 목적 추상 클래스는 자신을 상속받아 구현하는 모든 클래스가 자신의 하위 타입이 되는 것에 목적을 가지고 있다. 즉, 하위 클래스가 자신의 기능을 상속받아 그 기능을 확장을 하는 것에 목적을 가지고 있다. 따라서 추상 클..
Java8에 추가된 Stream API는 다량의 데이터 처리나 손쉬운 병렬 처리를 위해 만들어졌다. Stream API는 일반적으로 데이터를 담고 있는 Collection의 개념이 아니라 어떤 시퀀스 요소들의 순차 및 병렬 집계 작업을 지원해주는 API이다. Stream의 특징 스트림이 처리하는 데이터소스를 변경하지 않는다.(원본 데이터를 훼손하지 않는다.) 스트림으로 처리하는 데이터는 오직 한 번만 처리된다. 원소의 유한 혹은 무한 시퀀스를 나타낸다. 요소가 무한인 경우 Short Circuit 메서드로 제한할 수 있다. 근본적으로 지연 평가(Lazy Evaluation)을 사용한다. 이 덕분에 무한 스트림을 다룰 수 있게 된다. 손쉬운 병렬 처리를 지원한다. Stream의 핵심 추상 개념 스트림 파이..
Java8부터는 인터페이스에 추상 메서드 선언뿐만 아니라 구현체를 제공할 수 있게 되었다. default 메서드 dfault 메서드의 필요성 Java8 이전에는 인터페이스에 추상 메서드가 추가되면 해당 클래스를 구현한 모든 클래스에서 다시 재정의를 해줘야 하는 불편함이 있었다. 예를 들어, 다음과 같은 구조를 가진 클래스가 있다고 생각해보자. public interface Printable { void print(); } public class PrintName implements Printable { @Override public void print() { System.out.println("print name"); } } public class PrintAge implements Printable {..
메서드 레퍼런스는 람다 표현식으로 구현할 때 단 하나의 메서드만을 호출하는 경우 축약해서 매개변수 없이 사용할 수 있도록 해준다. // 람다 표현식 (s) -> System.out.println(s); // 메서드 레퍼런스 System.out::println; 기존에는 직접 구현을 통해 람다를 사용했었다. 하지만 이미 그 기능을 하는 메서드가 존재한다면 메서드 레퍼런스로 더 간단히 표현할 수 있다. 메서드 참조하는 방법 static 메서드 참조 타입::스태틱 메서드 형태로 표현한다. public class Greeting { private String name; public static hello(String name) { return "hello" + name; } } public class Run {..
람다 표현식은 메서드로 전달할 수 있는 익명 함수를 단순화한 것이라고 할 수 있다. 즉, 컴파일러의 추론에 의지해서 코드를 단순화하는 것이다. 람다 표현식의 기본 구조는 다음과 같다. (i) -> i + 10; (인자 리스트) -> { 바디 }의 형태를 가진다. 위의 예제처럼 바디가 한 줄로 표현될 경우 { }와 return문을 생략할 수 있다. 하지만 여러 줄이라면 { }와 return문을 명시적으로 선언해줘야 한다. (x, y) -> { System.out.println("x + y"); return x + y; } 인자 리스트 1. 인자가 없을 경우 구현해야 하는 추상 메서드가 파라미터를 아무것도 받지 않는 경우에 사용한다. Supplier getSomeNumber = () -> 10; 2. 인자가..
Java가 제공하는 주요 함수형 인터페이스 java.util.function은 Java에서 자주 사용되는 함수형 인터페이스를 미리 정의해둔 패키지이다. 대표적으로 다음과 같은 함수형 인터페이스가 존재한다. Function BiFunction Consumer Supplier Predicate UnaryOperator BinaryOperator 각 함수형 인터페이스에 대해 알아보자. Function T 타입을 받아서 R 타입을 리턴하는 함수형 인터페이스이다. Integer 타입을 받아서 Integer 타입을 리턴하는 간단한 예제를 살펴보자. public static void main(String[] args) { Function plus10 = (i) -> i + 10; System.out.println(p..
함수형 인터페이스(Functional Interface) 함수형 인터페이스는 추상 메서드를 하나만 가진 인터페이스를 말한다. // 함수형 인터페이스! public interface DoSomething { void doAnything(); } Java 8에 새롭게 추가된 default 메서드나 static 메서드가 함께 존재한다고 하더라도 추상 메서드가 하나라면 함수형 인터페이스이다. // 함수형 인터페이스! public interface DoSomething { void doAnything(); default void printDefault() { System.out.println("default"); } static void printStatic() { System.out.println("static..
어떤 요청에 대한 응답으로 JSON을 많이 이용하고 있다. 이때 필요한 Data만 전달받는 DTO를 만들고 적용해보자. (카카오톡 챗봇 예제를 이용해 진행했습니다.) 1. 역직렬화(Deserialize)란? byte로 변환된 Data를 원래대로 변환하는 기술을 역직렬화(Deserialize)라고 부른다. Json → Java Object 변환 2. 예제 카카오 챗봇에서는 요청과 응답을 JSON Data로 주고 받는다. 전달된 JSON Data를 통해 사용자를 식별하거나, 사용자가 원하는 동작을 파악할 수 있고 데이터를 컨트롤할 수 있게 된다. 하지만 내가 사용하고자 하는 정보가 명확히 정해져 있고 한정적이라면 보내지는 JSON Data를 모두 받아 처리할 필요가 없다. 예를 들면, { "intent": ..
1. JUnit5 - Assertion JUnit Jupiter는 다양한 Assertion 메서드가 포함되어있다. Assertion 클래스를 살펴보면 메서드는 모두 static 메서드이고, 오버로딩을 통해 다양한 타입을 지원하고 있다. 다양한 Assertion 메서드를 살펴보자. assertEqulas(expected, actual) 실제 값이 기대한 값과 같은지 확인 assertNotNull(actual) 실제 값이 null이 아닌지 확인 assertTrue(boolean) 다음 조건이 True인지 확인 assertAll(executables) 모든 구문을 확인 functional Interface인 excutables 타입을 매개변수로 받는다. assertThrows(expectedType, exec..