개발 공부 기록하기/01. JAVA & Kotlin 38

자바는 여전히 공짜다 (Java is Still Free, Oct 2021)

https://medium.com/@javachampions/java-is-still-free-3-0-0-ocrt-2021-bca75c88d23b Java Is Still Free 3.0.0 (Ocrt 2021) With the changes to Oracle JDK distribution and support, there has been considerable uncertainty over the rights to use Oracle JDK vs… medium.com 에 나오는 "요약글"만을 번역한 내용입니다. 원활한 전달을 위해 일부 의역이 있을 수 있습니다. Oracle JDK 배포와 지원 정책이 변화되며 Oracle JDK Oracle Open JDK 빌드 다양한 벤더사의 Open JDK 빌드 를..

코루틴이란 무엇인가? (루틴과 코루틴)

이번 시간에는 ‘코루틴’을 간단히 사용해 보면서 코루틴이 무엇인지~ 감을 잡아보도록 하자 도대체 코루틴이란 무엇일까? 코루틴을 영어로 살펴보면 co-routine 으로 여기서 접미어 co 는 ‘협력하는’ 이라는 의미가 있다. 뒤에 있는 routine 은 컴퓨터 공학에서 이야기하는 루틴으로 간단히 ‘함수’라고 생각해도 좋다. 그렇다면 co-routine 은 협력하는 루틴, 협력하는 함수라는 의미이다. 잠깐, 우리가 생각하는 그냥 루틴(함수)도 서로 호출과 반환을 주고받으며 협력을 한다. 그런데 협력하는 루틴이라니 도대체 그냥 루틴과 협력하는 루틴은 어떤 차이가 있길래 ‘협력하는’ 이라는 의미가 있을까? 다음 코드를 살펴보자. fun main() { println("START") newRoutine() pr..

코틀린 제네릭 - 배열과 리스트, 제네릭과 무공변

지난 시간의 문제를 정리해 보면, 우리는 금붕어 Cage에서 금붕어를 꺼내 물고기 Cage에 옮길 수 없었다. 하지만 사실은, 그냥 금붕어를 물고기 Cage에 넣는 것은 아무 문제가 없다. val cage = Cage2() cage.put(GoldFish("금붕어")) 물고기 Cage에 금붕어가 들어가는 것은 문제가 아니라는 의미이다. 그렇다면 도대체 왜 이런 차이가 발생하는 것일까??! 근본적인 이유를 알기 위해 우리는 상속관계의 의미를 살펴보아야 한다. 여기 상속 관계인 두 클래스가 있다. Number와 Int라고 해보자. Number는 Int의 상위 타입이고 Int는 Number의 하위 타입이다. 이때 다음과 같은 코드는 정상 동작할 수 있다. fun doSomething(num: Number) {..

코틀린 제네릭 - 제네릭과 타입 파라미터

제네릭은 추상화를 하는데 있어 굉장히 필수적인 기능이고, 정말 잘 활용되는 언어적 특징이다. 제네릭을 이해하기 위해 Cage 클래스를 만들어 보자. Cage 에는 여러 동물을 넣거나 꺼낼 수 있다. 가장 간단한 Cage 클래스는 다음과 같다. class Cage { private val animals: MutableList = mutableListOf() fun getFirst(): Animal { return animals.first() } fun put(animal: Animal) { this.animals.add(animal) } fun moveFrom(cage: Cage) { this.animals.addAll(cage.animals) } } 당연히 Animal 클래스도 필요하니 간단하게 다음과 ..

코틀린 + 스프링 ArgumentResolver 주의할 점

코틀린은 타입의 nullable 여부를 확실하게 지정해야 한다. 따라서 Long 타입과 Long? 타입은 java의 (primitive type) long 과 (reference type) Long 으로 컴파일 된다. 이런 이유로 스프링 ArgumentResolver에서 supportsParameter 를 구현할 때 다음과 같은 주의를 기울여야 한다. 다음 코드는 우리가 resolving 하려는 타입이 코틀린의 Long 인지 확인한다. ArgumentResolver를 활용할 때 흔히 작성하는 코드다. override fun supportsParameter(parameter: MethodParameter): Boolean { return parameter.getParameterAnnotation(커스텀어노..

mockk 간단 사용법

https://mockk.io/ MockK Provides DSL to mock behavior. Built from zero to fit Kotlin language. Supports named parameters, object mocks, coroutines and extension function mocking mockk.io mock 객체 생성하기 val domainRepository = mockk() Argument Matching 사용하기 특정 객체에 expected answer를 부여할때 파라미터를 지정해주어야 한다. matcher는 다음과 같은 느낌으로 동작한다 // 들어오는 파라미터가 1L 일때만 cycle을 반환 every { domainRepository.findById(1L) } r..

이펙티브 코틀린 간단 정리 (Effective Kotlin)

잘 몰랐거나, 인상깊은 부분 위주로만 정리 1장 안정성 안정성 : 크래시가 적으면 사용자와 개발자 모두에게 좋고, 상당한 비즈니스 가치를 제공한다. Item 1. 가변성을 제한하라 시간의 변화에 따라서 변하는 요소를 표현할 수 있다는 것은 유용하지만, 상태를 적절하게 관리하는 것이 생각보다 꽤 어렵다. 프로그램을 이해하고 디버그하기 힘들어진다. 시점에 따라 값이 달라질 수 있기 때문에 코드의 실행을 추론하기 어려워진다. 멀티스레드 프로그램일 때는 적절한 동기화가 필요하다. 테스트하기 어렵다. 상태 변경이 일어날 때 이러한 변경을 다른 부분에 알려야 하는 경우가 있다. 가변성은 시스템의 상태를 나타내기 위한 주요한 방법이다. 하지만, 변경이 일어나야 하는 부분을 신중하고 확실하게 결정하고 사용해야 한다. ..

Junit5 Extension 알아보기 (org.junit.jupiter.api.extension)

Extension 모든 extension을 위한 마커 인터페이스이다. Extension은 @ExtendWith 를 통해 선언적으로 등록될 수도 있고, @RegisterExtension 을 사용해 프로그램에 따라 적용될 수도 있가. ServiceLoader 매커니즘을 이용해 자동 등록될 수도 있다. ServiceLoader 또는 @ExtendWith 를 이용해 등록되는 Extension 구현체는 default constructor를 무조건 가지고 있어야 한다. @ExtendWith 를 이용해 등록될 때 default constructor는 반드시 public이 아니어도 된다. ServiceLoader를 통해 등록될 때 default constructor는 반드시 public 이어야 한다. @Register..

[코틀린 docs] 코틀린의 타입

코틀린의 공식 문서, Basic Types(https://kotlinlang.org/docs/reference/basic-types.html)를 간단히 정리하며 한 번더 생각해볼만한 것을 정리한 기록입니다. 코틀린 primitive type과 NULL 코틀린에서 중요하게 생각하는 철학 중 하나는 NULL이 될 수도 있는 타입과 NULL이 절대 들어가지 않을 타입을 명확히 구분하겠다는 것이다. 또한, 내부적으로 primitive type이 존재하고, 실제 연산을 할 때도 primitive type으로 처리하지만 타입은 모두 객체 타입으로 간주된다. 이게 무슨 말인가 하면 int number = 3; 이라는 자바 코드가 존재한다고 해보자. 이때 int는 Integer 라는 객체와 명확히 구분되며, primi..

[코틀린] companion object이란?

오늘은 companion object에 대해 알아볼 예정이다. 역시나 Java 로 코드를 살펴보고 Kotlin으로 바꿔보도록 하자 Java에서의 상수 public class Person { public static final int MAX_AGE = 500; } public static void main() { System.out.println(Person.MAX_AGE); } 간단한 코드이다. Person 클래스 내부에 MAX_AGE 라는 상수가 public 접근 제한자로 존재하고, 이는 외부에서 Person.MAX_AGE로 접근할 수 있다. 만약 Person 클래스 내부에서만 접근하게 하고 싶다면 public을 private으로 바꿀 수 있다. 클래스와 인스턴스 관점에서 바라보자면, static 필드..